added suppport for unexpected udp/138 packets
authorAndrew Tridgell <tridge@samba.org>
Mon, 3 Jan 2000 06:30:50 +0000 (06:30 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 3 Jan 2000 06:30:50 +0000 (06:30 +0000)
I also fixed up the lookup_pdc_name() code so that it now works, even
with a NT server that insists on replying to udp/138.

The method I used to match packets was to use the mailslot string as a
datagram ID. The true dgm_id doesn't work as NT doesn't set it
correctly. uggh.

PS: Jeremy, I had to change your code quite a bit, are you sure this
worked with a Samba PDC?? The code looked broken, it got the offsets
wrong in the SMB portion of the packet and filled in the IP
incorrectly.
(This used to be commit 32f66f4ea63038cb4b3785bdf1762abdde076f5d)

source3/include/proto.h
source3/libsmb/namequery.c
source3/libsmb/nmblib.c
source3/libsmb/unexpected.c
source3/nmbd/nmbd_packets.c
source3/smbd/password.c

index 2c2bcd71c10b83af450916d786713ff67caeb70c..92a57c09503e97d7f4c8271f5e8fe834d57f9a92 100644 (file)
@@ -626,7 +626,9 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
 int build_packet(char *buf, struct packet_struct *p);
 BOOL send_packet(struct packet_struct *p);
 struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
-struct packet_struct *receive_reply_packet(int fd, int t, int trn_id);
+struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id);
+struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name);
+BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name);
 void sort_query_replies(char *data, int n, struct in_addr ip);
 
 /*The following definitions come from  libsmb/nterr.c  */
@@ -682,7 +684,7 @@ char *smb_errstr(char *inbuf);
 
 void unexpected_packet(struct packet_struct *p);
 void clear_unexpected(time_t t);
-struct packet_struct *receive_unexpected_137(int trn_id);
+struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, char *mailslot_name);
 
 /*The following definitions come from  locking/locking.c  */
 
index 0cf89149a8f957454b953ef8927446cd385ab6bd..3898a721c694d3413f0c20fd4e937fd9b6a7aaf0 100644 (file)
@@ -161,7 +161,7 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
                  retries--;
          }
 
-         if ((p2=receive_reply_packet(fd,90,nmb->header.name_trn_id))) {     
+         if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
                  struct nmb_packet *nmb2 = &p2->packet.nmb;
                  debug_nmb_packet(p2);
 
@@ -269,7 +269,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
                  retries--;
          }
          
-         if ((p2=receive_reply_packet(fd,90,nmb->header.name_trn_id))) {     
+         if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
                  struct nmb_packet *nmb2 = &p2->packet.nmb;
                  debug_nmb_packet(p2);
                  
@@ -712,259 +712,189 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip)
        return False;
 }
 
-/********************************************************
- Internal function to extract the MACHINE<0x20> name.
-*********************************************************/
-
-static void _lookup_pdc_name(char *p, char *master,char *rname)
-{
-  int numnames = CVAL(p,0);
-
-  *rname = '\0';
-
-  p += 1;
-  while (numnames--) {
-    int type = CVAL(p,15);
-    if(type == 0x20) {
-      StrnCpy(rname,p,15);
-      trim_string(rname,NULL," ");
-      return;
-    }
-    p += 18;
-  }
-}
 
 /********************************************************
  Lookup a PDC name given a Domain name and IP address.
 *********************************************************/
-
 BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name)
 {
-#if !defined(I_HATE_WINDOWS_REPLY_CODE)
-
-  fstring pdc_name;
-  BOOL ret;
-
-  /*
-   * Due to the fact win WinNT *sucks* we must do a node status
-   * query here... JRA.
-   */
-
-  int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
-
-  if(sock == -1)
-    return False;
-
-  *pdc_name = '\0';
-
-  ret = internal_name_status(sock,"*SMBSERVER",0x20,True,
-                            *pdc_ip,NULL,pdc_name,False,
-                            _lookup_pdc_name);
-
-  close(sock);
-
-  if(ret && *pdc_name) {
-    fstrcpy(ret_name, pdc_name);
-    return True;
-  }
-
-  return False;
-
-#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
-  /*
-   * Sigh. I *love* this code, it took me ages to get right and it's
-   * completely *USELESS* because NT 4.x refuses to send the mailslot
-   * reply back to the correct port (it always uses 138).
-   * I hate NT when it does these things... JRA.
-   */
-
-  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 = "\\MAILSLOT\\NET\\NETLOGON";
-  char buffer[1024];
-  char *bufp;
-  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);
-  fstrcpy(bufp,"\\MAILSLOT\\NET\\GETDC411");
-  bufp += (strlen(bufp) + 1);
-  bufp = align2(bufp, buffer);
-  dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1);
-  bufp = skip_unicode_string(bufp, 1);
-  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 = generate_trn_id();
-  dgram->header.source_ip = sock_name.sin_addr;
-  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,scope);
-  make_nmb_name(&dgram->dest_name,domain,0x1B,scope);
-
-  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_packet(sock,NMB_PACKET,90))) {
-      struct nmb_packet *nmb2 = &p_ret->packet.nmb;
-      struct dgram_packet *dgram2 = &p_ret->packet.dgram;
-      char *buf;
-      char *buf2;
-
-      debug_nmb_packet(p_ret);
-
-      if (memcmp(&p.ip, &p_ret->ip, sizeof(p.ip))) {
-        /* 
-         * Not for us.
-         */
-        DEBUG(0,("lookup_pdc_name: datagram return IP %s doesn't match\n", inet_ntoa(p_ret->ip) ));
-        free_packet(p_ret);
-        continue;
-      }
+       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 = "\\MAILSLOT\\NET\\NETLOGON";
+       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;
+       }
 
-      buf = &dgram2->data[0];
-      buf -= 4;
+       /*
+        * Create the request data.
+        */
 
-      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;
-      }
+       memset(buffer,'\0',sizeof(buffer));
+       bufp = buffer;
+       SSVAL(bufp,0,QUERYFORPDC);
+       bufp += 2;
+       fstrcpy(bufp,srcname);
+       bufp += (strlen(bufp) + 1);
+       slprintf(bufp, sizeof(fstring), "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
+       mailslot_name = bufp;
+       bufp += (strlen(bufp) + 1);
+       bufp = align2(bufp, buffer);
+       dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1);
+       bufp = skip_unicode_string(bufp, 1);
+       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,scope);
+       make_nmb_name(&dgram->dest_name,domain,0x1B,scope);
+       
+       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--;
+               }
 
-      len = SVAL(buf,smb_vwv11);
-      buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
+               if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
+                       struct dgram_packet *dgram2 = &p_ret->packet.dgram;
+                       char *buf;
+                       char *buf2;
 
-      if (len <= 0) {
-        DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
-        free_packet(p_ret);
-        continue;
-      }
+                       buf = &dgram2->data[0];
+                       buf -= 4;
 
-      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),CVAL(buf2,0),len));
+                       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;
+                       }
 
-      if(SVAL(buf,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;
-      }
+                       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));
 
-      buf += 2;
-      /* Note this is safe as it is a bounded strcpy. */
-      fstrcpy(ret_name, buf);
-      ret_name[sizeof(fstring)-1] = '\0';
-      close(sock);
-      free_packet(p_ret);
-      return True;
-    }
-  }
+                       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;
+                       }
 
-  close(sock);
-  return False;
-#endif /* I_HATE_WINDOWS_REPLY_CODE */
+                       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;
 }
 
+
 /********************************************************
  Get the IP address list of the PDC/BDC's of a Domain.
 *********************************************************/
-
 BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count)
 {
        return internal_resolve_name(group, 0x1C, ip_list, count);
index 13f7e1112394a466ca0cd0392b91960dd96976bc..9ddfd3a6c665ede7a7db35a70733f3fbae92a034 100644 (file)
@@ -979,7 +979,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
   queue. The packet must be a reply packet and have the specified trn_id
   The timeout is in milliseconds
   ***************************************************************************/
-struct packet_struct *receive_reply_packet(int fd, int t, int trn_id)
+struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
 {
        struct packet_struct *p;
 
@@ -992,7 +992,48 @@ struct packet_struct *receive_reply_packet(int fd, int t, int trn_id)
        if (p) free_packet(p);
 
        /* try the unexpected packet queue */
-       return receive_unexpected_137(trn_id);
+       return receive_unexpected(NMB_PACKET, trn_id, NULL);
+}
+
+/****************************************************************************
+  receive a UDP/138 packet either via UDP or from the unexpected packet
+  queue. The packet must be a reply packet and have the specified dgm_id
+  The timeout is in milliseconds
+  ***************************************************************************/
+struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
+{
+       struct packet_struct *p;
+
+       p = receive_packet(fd, DGRAM_PACKET, t);
+
+       if (p && match_mailslot_name(p, mailslot_name)) {
+               return p;
+       }
+       if (p) free_packet(p);
+
+       /* try the unexpected packet queue */
+       return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
+}
+
+
+/****************************************************************************
+ see if a datagram has the right mailslot name
+***************************************************************************/
+BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
+{
+       struct dgram_packet *dgram = &p->packet.dgram;
+       char *buf;
+
+       buf = &dgram->data[0];
+       buf -= 4;
+
+       buf = smb_buf(buf);
+
+       if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
+               return True;
+       }
+
+       return False;
 }
 
 
index 57fad7c6961e40eb034eff75d00c2ee382e329e6..5106ef60f7f032fd77c8c89c2078ceb935d938d9 100644 (file)
@@ -111,24 +111,28 @@ void clear_unexpected(time_t t)
 
 
 static struct packet_struct *matched_packet;
-static int match_trn_id;
+static int match_id;
+static enum packet_type match_type;
+static char *match_name;
 
 /****************************************************************************
 tdb traversal fn to find a matching 137 packet
   **************************************************************************/
-static int traverse_match_137(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf)
+static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf)
 {
        struct unexpected_key key;
        struct packet_struct *p;
 
        memcpy(&key, kbuf.dptr, sizeof(key));
 
-       if (key.packet_type != NMB_PACKET) return 0;
+       if (key.packet_type != match_type) return 0;
 
-       p = parse_packet(dbuf.dptr, dbuf.dsize, NMB_PACKET);
+       p = parse_packet(dbuf.dptr, dbuf.dsize, match_type);
 
-       if (p->packet_type == NMB_PACKET &&
-           p->packet.nmb.header.name_trn_id == match_trn_id) {
+       if ((match_type == NMB_PACKET && 
+            p->packet.nmb.header.name_trn_id == match_id) ||
+           (match_type == DGRAM_PACKET && 
+            match_mailslot_name(p, match_name))) {
                matched_packet = p;
                return -1;
        }
@@ -142,7 +146,8 @@ static int traverse_match_137(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf)
 /****************************************************************************
 check for a particular packet in the unexpected packet queue
   **************************************************************************/
-struct packet_struct *receive_unexpected_137(int trn_id)
+struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, 
+                                        char *mailslot_name)
 {
        TDB_CONTEXT *tdb2;
 
@@ -150,9 +155,11 @@ struct packet_struct *receive_unexpected_137(int trn_id)
        if (!tdb2) return NULL;
 
        matched_packet = NULL;
-       match_trn_id = trn_id;
+       match_id = id;
+       match_type = packet_type;
+       match_name = mailslot_name;
 
-       tdb_traverse(tdb2, traverse_match_137);
+       tdb_traverse(tdb2, traverse_match);
 
        tdb_close(tdb2);
 
index 77bdb298168f755fef0f301e83be803801aa853d..3bf009f2c291a3577924aea331b221d7880fdccd 100644 (file)
@@ -1204,7 +1204,6 @@ static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
 /****************************************************************************
   Process udp 138 datagrams
 ****************************************************************************/
-
 static void process_dgram(struct packet_struct *p)
 {
   char *buf;
@@ -1215,20 +1214,22 @@ static void process_dgram(struct packet_struct *p)
   /* If we aren't listening to the destination name then ignore the packet */
   if (!listening(p,&dgram->dest_name))
   {
-    DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
-           nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
-    return;
+         unexpected_packet(p);
+         DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
+                  nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
+         return;
   }
 
   if (dgram->header.msg_type != 0x10 &&
       dgram->header.msg_type != 0x11 &&
       dgram->header.msg_type != 0x12) 
   {
-    /* Don't process error packets etc yet */
-    DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
-           an error packet of type %x\n",
-           nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
-    return;
+         unexpected_packet(p);
+         /* Don't process error packets etc yet */
+         DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
+an error packet of type %x\n",
+                  nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
+         return;
   }
 
   buf = &dgram->data[0];
@@ -1275,6 +1276,8 @@ static void process_dgram(struct packet_struct *p)
     process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
     return;
   }
+
+  unexpected_packet(p);
 }
 
 /****************************************************************************
index 9792c9ebc80dd845a3fe16573276ea45936c9996..ca588c668149607a22436f5367c3e6f6832c418c 100644 (file)
@@ -959,16 +959,18 @@ struct cli_state *server_cryptkey(void)
        struct cli_state *cli;
        fstring desthost;
        struct in_addr dest_ip;
-       char *p;
-    BOOL connected_ok = False;
+       char *p, *pserver;
+       BOOL connected_ok = False;
 
        cli = server_client();
 
        if (!cli_initialise(cli))
                return NULL;
 
-        p = lp_passwordserver();
-        while(p && next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
+        pserver = strdup(lp_passwordserver());
+       p = pserver;
+
+        while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
                standard_sub_basic(desthost);
                strupper(desthost);
 
@@ -989,6 +991,8 @@ struct cli_state *server_cryptkey(void)
                }
        }
 
+       free(pserver);
+
        if (!connected_ok) {
                DEBUG(0,("password server not available\n"));
                cli_shutdown(cli);
@@ -1249,15 +1253,79 @@ static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, un
    * Ignore addresses we have already tried.
    */
 
-  if(ip_equal(ipzero, *ip))
-    return False;
+  if (ip_equal(ipzero, *ip))
+         return False;
 
-  if(!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name))
-    return False;
+  if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name))
+         return False;
 
   return connect_to_domain_password_server(pcli, dc_name, trust_passwd);
 }
 
+
+
+/***********************************************************************
+ We have been asked to dynamcially determine the IP addresses of
+ the PDC and BDC's for this DOMAIN, and query them in turn.
+************************************************************************/
+static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd)
+{
+       struct in_addr *ip_list = NULL;
+       int count = 0;
+       int i;
+       BOOL connected_ok = False;
+
+       if (!get_dc_list(lp_workgroup(), &ip_list, &count))
+               return False;
+
+       /*
+        * Firstly try and contact a PDC/BDC who has the same
+        * network address as any of our interfaces.
+        */
+       for(i = 0; i < count; i++) {
+               if(!is_local_net(ip_list[i]))
+                       continue;
+
+               if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) 
+                       break;
+               
+               ip_list[i] = ipzero; /* Tried and failed. */
+       }
+
+       /*
+        * Secondly try and contact a random PDC/BDC.
+        */
+       if(!connected_ok) {
+               i = (sys_random() % count);
+
+               if (!(connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd)))
+                       ip_list[i] = ipzero; /* Tried and failed. */
+       }
+
+       /*
+        * Finally go through the IP list in turn, ignoring any addresses
+        * we have already tried.
+        */
+       if(!connected_ok) {
+               /*
+                * Try and connect to any of the other IP addresses in the PDC/BDC list.
+                * Note that from a WINS server the #1 IP address is the PDC.
+                */
+               for(i = 0; i < count; i++) {
+                       if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd)))
+                               break;
+               }
+       }
+
+       if(ip_list != NULL)
+               free((char *)ip_list);
+
+
+       return connected_ok;
+}
+
+
+
 /***********************************************************************
  Do the same as security=server, but using NT Domain calls and a session
  key from the machine password.
@@ -1273,7 +1341,7 @@ BOOL domain_client_validate( char *user, char *domain,
   unsigned char local_nt_reponse[24];
   unsigned char trust_passwd[16];
   fstring remote_machine;
-  char *p;
+  char *p, *pserver;
   NET_ID_INFO_CTR ctr;
   NET_USER_INFO_3 info3;
   struct cli_state cli;
@@ -1349,75 +1417,20 @@ BOOL domain_client_validate( char *user, char *domain,
    * PDC/BDC. Contact each in turn and try and authenticate.
    */
 
-  p = lp_passwordserver();
-  while(!connected_ok && p &&
-        next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) {
-    if(strequal(remote_machine, "*")) {
-
-      /*
-       * We have been asked to dynamcially determine the IP addresses of
-       * the PDC and BDC's for this DOMAIN, and query them in turn.
-       */
-
-      struct in_addr *ip_list = NULL;
-      int count = 0;
-      int i;
-
-      if(!get_dc_list(lp_workgroup(), &ip_list, &count))
-        continue;
-
-      /*
-       * Firstly try and contact a PDC/BDC who has the same
-       * network address as any of our interfaces.
-       */
-
-      for(i = 0; i < count; i++) {
-        if(!is_local_net(ip_list[i]))
-          continue;
-
-        if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd)))
-          break;
-
-        ip_list[i] = ipzero; /* Tried and failed. */
-      }
-
-      /*
-       * Secondly try and contact a random PDC/BDC.
-       */
-
-      if(!connected_ok) {
-        i = (sys_random() % count);
+  pserver = strdup(lp_passwordserver());
+  p = pserver;
 
-        if(!(connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd)))
-          ip_list[i] = ipzero; /* Tried and failed. */
-      }
-
-      /*
-       * Finally go through the IP list in turn, ignoring any addresses
-       * we have already tried.
-       */
-
-      if(!connected_ok) {
-
-        /*
-         * Try and connect to any of the other IP addresses in the PDC/BDC list.
-         * Note that from a WINS server the #1 IP address is the PDC.
-         */
-
-        for(i = 0; i < count; i++) {
-          if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd)))
-            break;
-        }
-      }
-
-      if(ip_list != NULL)
-        free((char *)ip_list);
-
-    } else {
-      connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd);
-    }
+  while (!connected_ok &&
+        next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) {
+         if(strequal(remote_machine, "*")) {
+                 connected_ok = find_connect_pdc(&cli, trust_passwd);
+         } else {
+                 connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd);
+         }
   }
 
+  free(pserver);
+
   if (!connected_ok) {
     DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
     cli_shutdown(&cli);