Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: [Wireshark-dev] [PATCH] fix SMB_NETLOGON cmd 0x17,0x19

From: "Stefan (metze) Metzmacher" <metze@xxxxxxxxx>
Date: Thu, 23 Nov 2006 08:56:46 +0100
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I created two patches:

1.)
 move the handling of the compressed strings in CLDAP 'netlogon' replies
 into a generic place.

2.)
 implement dissection of SMB_NETLOGON cmd's 0x17 and 0x19

Can someone please apply them?

metze
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFFZVQ9m70gjA5TCD8RArmNAJwIUYqIP9oG0wtzc5rzeN9F5te1pQCgjapr
uT6ue5VBleQVcFtX95b+IJA=
=WvKu
-----END PGP SIGNATURE-----
Index: epan/dissectors/packet-smb-common.c
===================================================================
--- epan/dissectors/packet-smb-common.c	(Revision 19935)
+++ epan/dissectors/packet-smb-common.c	(Arbeitskopie)
@@ -125,9 +125,87 @@
 	return 	offset+len;
 }
 
+static int dissect_ms_compressed_string_internal(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
+{
+  guint8 len;
+
+  len=tvb_get_guint8(tvb, offset);
+  offset+=1;
+  *str=0;
+
+  while(len){
+    /* add potential field separation dot */
+    if(prepend_dot){
+      if(!maxlen){
+        *str=0;
+        return offset;
+      }
+      maxlen--;
+      *str++='.';
+      *str=0;
+    }
+
+    if(len==0xc0){
+      int new_offset;
+      /* ops its a mscldap compressed string */
+
+      new_offset=tvb_get_guint8(tvb, offset);
+      if (new_offset == offset - 1)
+        THROW(ReportedBoundsError);
+      offset+=1;
+
+      dissect_ms_compressed_string_internal(tvb, new_offset, str, maxlen, FALSE);
+
+      return offset;
+    }
+
+    prepend_dot=TRUE;
+
+    if(maxlen<=len){
+      if(maxlen>3){
+        *str++='.';
+        *str++='.';
+        *str++='.';
+      }
+      *str=0;
+      return offset; /* will mess up offset in caller, is unlikely */
+    }
+    tvb_memcpy(tvb, str, offset, len);
+    str+=len;
+    *str=0;
+    maxlen-=len;
+    offset+=len;
+
+
+    len=tvb_get_guint8(tvb, offset);
+    offset+=1;
+  }
+  *str=0;
+  return offset;
+}
+
 /* Max string length for displaying Unicode strings.  */
 #define	MAX_UNICODE_STR_LEN	256
 
+int dissect_ms_compressed_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index,
+				 gboolean prepend_dot, char **data)
+{
+	int old_offset=offset;
+	char *str;
+	int len;
+
+	len = MAX_UNICODE_STR_LEN+3+1;
+	str=ep_alloc(len);
+
+	offset=dissect_ms_compressed_string_internal(tvb, offset, str, len, prepend_dot);
+	proto_tree_add_string(tree, hf_index, tvb, old_offset, offset-old_offset, str);
+
+	if (data)
+		*data = str;
+
+	return offset;
+}
+
 /* Turn a little-endian Unicode '\0'-terminated string into a string we
    can display.
    XXX - for now, we just handle the ISO 8859-1 characters.
Index: epan/dissectors/packet-smb-common.h
===================================================================
--- epan/dissectors/packet-smb-common.h	(Revision 19935)
+++ epan/dissectors/packet-smb-common.h	(Arbeitskopie)
@@ -36,6 +36,9 @@
 
 int display_ms_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index, char **data);
 
+int dissect_ms_compressed_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index,
+				 gboolean prepend_dot, char **data);
+
 const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
     gboolean useunicode, int *len, gboolean nopad, gboolean exactlen,
     guint16 *bcp);
Index: epan/dissectors/packet-ldap.c
===================================================================
--- epan/dissectors/packet-ldap.c	(Revision 19935)
+++ epan/dissectors/packet-ldap.c	(Arbeitskopie)
@@ -94,6 +94,7 @@
 #include <epan/strutil.h>
 #include <epan/dissectors/packet-tcp.h>
 #include <epan/dissectors/packet-windows-common.h>
+#include <epan/dissectors/packet-smb-common.h>
 #include <epan/dissectors/packet-dcerpc.h>
 
 #include "packet-frame.h"
@@ -3427,65 +3428,6 @@
     }
 }
 
-static int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
-{
-  guint8 len;
-
-  len=tvb_get_guint8(tvb, offset);
-  offset+=1;
-  *str=0;
-
-  while(len){
-    /* add potential field separation dot */
-    if(prepend_dot){
-      if(!maxlen){
-        *str=0;
-        return offset;
-      }
-      maxlen--;
-      *str++='.';
-      *str=0;
-    }
-
-    if(len==0xc0){
-      int new_offset;
-      /* ops its a mscldap compressed string */
-
-      new_offset=tvb_get_guint8(tvb, offset);
-      if (new_offset == offset - 1)
-        THROW(ReportedBoundsError);
-      offset+=1;
-
-      dissect_mscldap_string(tvb, new_offset, str, maxlen, FALSE);
-
-      return offset;
-    }
-
-    prepend_dot=TRUE;
-
-    if(maxlen<=len){
-      if(maxlen>3){
-        *str++='.';
-        *str++='.';
-        *str++='.';
-      }
-      *str=0;
-      return offset; /* will mess up offset in caller, is unlikely */
-    }
-    tvb_memcpy(tvb, str, offset, len);
-    str+=len;
-    *str=0;
-    maxlen-=len;
-    offset+=len;
-
-
-    len=tvb_get_guint8(tvb, offset);
-    offset+=1;
-  }
-  *str=0;
-  return offset;
-}
-
 /* These flag bits were found to be defined in the samba sources.
  * I hope they are correct (but have serious doubts about the CLOSEST
  * bit being used or being meaningful).
@@ -3583,8 +3525,7 @@
 
 static void dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
-  int old_offset, offset=0;
-  char str[256];
+  int offset=0;
 
   ldm_tree = NULL;
 
@@ -3603,44 +3544,28 @@
   offset += 16;
 
   /* Forest */
-  old_offset=offset;
-  offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
-  proto_tree_add_string(tree, hf_mscldap_forest, tvb, old_offset, offset-old_offset, str);
+  offset=dissect_ms_compressed_string(tvb, tree, offset, hf_mscldap_forest, FALSE, NULL);
 
   /* Domain */
-  old_offset=offset;
-  offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
-  proto_tree_add_string(tree, hf_mscldap_domain, tvb, old_offset, offset-old_offset, str);
+  offset=dissect_ms_compressed_string(tvb, tree, offset, hf_mscldap_domain, FALSE, NULL);
 
   /* Hostname */
-  old_offset=offset;
-  offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
-  proto_tree_add_string(tree, hf_mscldap_hostname, tvb, old_offset, offset-old_offset, str);
+  offset=dissect_ms_compressed_string(tvb, tree, offset, hf_mscldap_hostname, FALSE, NULL);
 
   /* NetBios Domain */
-  old_offset=offset;
-  offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
-  proto_tree_add_string(tree, hf_mscldap_nb_domain, tvb, old_offset, offset-old_offset, str);
+  offset=dissect_ms_compressed_string(tvb, tree, offset, hf_mscldap_nb_domain, FALSE, NULL);
 
   /* NetBios Hostname */
-  old_offset=offset;
-  offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
-  proto_tree_add_string(tree, hf_mscldap_nb_hostname, tvb, old_offset, offset-old_offset, str);
+  offset=dissect_ms_compressed_string(tvb, tree, offset, hf_mscldap_nb_hostname, FALSE, NULL);
 
   /* User */
-  old_offset=offset;
-  offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
-  proto_tree_add_string(tree, hf_mscldap_username, tvb, old_offset, offset-old_offset, str);
+  offset=dissect_ms_compressed_string(tvb, tree, offset, hf_mscldap_username, FALSE, NULL);
 
   /* Site */
-  old_offset=offset;
-  offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
-  proto_tree_add_string(tree, hf_mscldap_sitename, tvb, old_offset, offset-old_offset, str);
+  offset=dissect_ms_compressed_string(tvb, tree, offset, hf_mscldap_sitename, FALSE, NULL);
 
   /* Client Site */
-  old_offset=offset;
-  offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
-  proto_tree_add_string(tree, hf_mscldap_clientsitename, tvb, old_offset, offset-old_offset, str);
+  offset=dissect_ms_compressed_string(tvb, tree, offset, hf_mscldap_clientsitename, FALSE, NULL);
 
   /* Version */
   proto_tree_add_item(tree, hf_mscldap_netlogon_version, tvb, offset, 4, TRUE);


Index: epan/dissectors/packet-smb-logon.c
===================================================================
--- epan/dissectors/packet-smb-logon.c	(Revision 19935)
+++ epan/dissectors/packet-smb-logon.c	(Arbeitskopie)
@@ -36,12 +36,18 @@
 #include "packet-smb-common.h"
 
 static int proto_smb_logon = -1;
+static int proto_smb_netlogon = -1;
+static int proto_smb_ntlogon = -1;
 static int hf_command = -1;
 static int hf_computer_name = -1;
 static int hf_unicode_computer_name = -1;
+static int hf_unknown_int = -1;
 static int hf_server_name = -1;
 static int hf_user_name = -1;
 static int hf_domain_name = -1;
+static int hf_server_dns_name = -1;
+static int hf_forest_dns_name = -1;
+static int hf_domain_dns_name = -1;
 static int hf_mailslot_name = -1;
 static int hf_pdc_name = -1;
 static int hf_unicode_pdc_name = -1;
@@ -75,6 +81,15 @@
 static int hf_large_serial = -1;
 static int hf_nt_date_time = -1;
 
+static int hf_unknown8 = -1;
+static int hf_unknown32 = -1;
+
+static int hf_domain_guid = -1;
+static int hf_server_ip = -1;
+
+static int hf_server_site_name = -1;
+static int hf_client_site_name = -1;
+
 static int ett_smb_logon = -1;
 static int ett_smb_account_flags = -1;
 static int ett_smb_db_info = -1;
@@ -531,7 +546,6 @@
 }
 
 
-
 static int
 dissect_smb_sam_logon_req(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
 {
@@ -729,6 +743,81 @@
 }
 
 static int
+dissect_smb_pdc_response_ads(tvbuff_t *tvb, packet_info *pinfo _U_,
+	proto_tree *tree, int offset)
+{
+	/* Netlogon command 0x17 - decode the response from PDC ADS */
+	/* Netlogon command 0x19 - decode the response from PDC ADS USER ?*/
+
+	/* Align to four-byte boundary */
+	offset = ((offset + 3)/4)*4;
+
+	/* unknown uint32 type */
+	proto_tree_add_item(tree, hf_unknown32, tvb, offset, 4, TRUE);
+	offset += 4;
+
+	/* Domain GUID */
+	proto_tree_add_item(tree, hf_domain_guid, tvb, offset, 16, TRUE);
+	offset += 16;
+
+	/* forest dns name */
+	offset=dissect_ms_compressed_string(tvb, tree, offset, hf_forest_dns_name, FALSE, NULL);
+
+	/* domain dns name */
+	offset=dissect_ms_compressed_string(tvb, tree, offset, hf_domain_dns_name, FALSE, NULL);
+
+	/* server dns name */
+	offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_dns_name, FALSE, NULL);
+
+	/* domain name */
+	offset=dissect_ms_compressed_string(tvb, tree, offset, hf_domain_name, FALSE, NULL);
+
+	/* server name */
+	offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_name, FALSE, NULL);
+
+	/* user name */
+	offset=dissect_ms_compressed_string(tvb, tree, offset, hf_user_name, FALSE, NULL);
+
+	/* server_site name */
+	offset=dissect_ms_compressed_string(tvb, tree, offset, hf_server_site_name, FALSE, NULL);
+
+	/* client_site name */
+	offset=dissect_ms_compressed_string(tvb, tree, offset, hf_client_site_name, FALSE, NULL);
+
+	/* unknown uint8 type */
+	proto_tree_add_item(tree, hf_unknown8, tvb, offset, 1, TRUE);
+	offset += 1;
+
+	/* unknown uint32 type */
+	proto_tree_add_item(tree, hf_unknown32, tvb, offset, 4, TRUE);
+	offset += 4;
+
+	/* server ip */
+	proto_tree_add_item(tree, hf_server_ip, tvb, offset, 4, FALSE);
+	offset += 4;
+
+	/* unknown uint32 type */
+	proto_tree_add_item(tree, hf_unknown32, tvb, offset, 4, TRUE);
+	offset += 4;
+
+	/* unknown uint32 type */
+	proto_tree_add_item(tree, hf_unknown32, tvb, offset, 4, TRUE);
+	offset += 4;
+
+	/* NT version */
+	proto_tree_add_item(tree, hf_nt_version, tvb, offset, 4, TRUE);
+	offset += 4;
+
+	/* LMNT token */
+	offset = display_LMNT_token(tvb, offset, tree);
+
+	/* LM token */
+	offset = display_LM_token(tvb, offset, tree);
+
+	return offset;
+}
+
+static int
 dissect_smb_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
 {
 	/* display data as unknown */
@@ -821,9 +910,9 @@
 	dissect_smb_unknown,        /* 0x14 (SAM Response during LOGON Pause) */
 	dissect_smb_unknown,        /* 0x15 (SAM Response User Unknown)	*/
 	dissect_smb_unknown,        /* 0x16 (SAM Response to Interrogate)*/
-	dissect_smb_unknown,        /* 0x17 (SAM AD response User Unknown*/
+	dissect_smb_pdc_response_ads,        /* 0x17 (SAM AD response User Unknown*/
 	dissect_smb_unknown,        /* 0x18 (Unknown command)		*/
-	dissect_smb_unknown         /* 0x19 (SAM LOGON AD response)	*/
+	dissect_smb_pdc_response_ads         /* 0x19 (SAM LOGON AD response)	*/
 };
 
 
@@ -890,6 +979,10 @@
 			{ "Server Name", "smb_netlogon.server_name", FT_STRING, BASE_NONE,
 			  NULL, 0, "SMB NETLOGON Server Name", HFILL }},
 
+		{ &hf_server_dns_name,
+			{ "Server DNS Name", "smb_netlogon.server_dns_name", FT_STRING, BASE_NONE,
+			  NULL, 0, "SMB NETLOGON Server DNS Name", HFILL }},
+
 		{ &hf_user_name,
 			{ "User Name", "smb_netlogon.user_name", FT_STRING, BASE_NONE,
 			  NULL, 0, "SMB NETLOGON User Name", HFILL }},
@@ -898,6 +991,14 @@
 			{ "Domain Name", "smb_netlogon.domain_name", FT_STRING, BASE_NONE,
 			  NULL, 0, "SMB NETLOGON Domain Name", HFILL }},
 
+		{ &hf_domain_dns_name,
+			{ "Domain DNS Name", "smb_netlogon.domain_dns_name", FT_STRING, BASE_NONE,
+			  NULL, 0, "SMB NETLOGON Domain DNS Name", HFILL }},
+
+		{ &hf_forest_dns_name,
+			{ "Forest DNS Name", "smb_netlogon.forest_dns_name", FT_STRING, BASE_NONE,
+			  NULL, 0, "SMB NETLOGON Forest DNS Name", HFILL }},
+
 		{ &hf_mailslot_name,
 			{ "Mailslot Name", "smb_netlogon.mailslot_name", FT_STRING, BASE_NONE,
 			  NULL, 0, "SMB NETLOGON Mailslot Name", HFILL }},
@@ -1027,6 +1128,30 @@
 		{ &hf_nt_date_time,
 			{ "NT Date/Time", "smb_netlogon.nt_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
 			  NULL, 0, "SMB NETLOGON NT Date/Time", HFILL }},
+
+		{ &hf_unknown8,
+			{ "Unknown", "smb_netlogon.unknown", FT_UINT8, BASE_HEX,
+			  NULL, 0, "Unknown", HFILL }},
+
+		{ &hf_unknown32,
+			{ "Unknown", "smb_netlogon.unknown", FT_UINT32, BASE_HEX,
+			  NULL, 0, "Unknown", HFILL }},
+
+		{ &hf_domain_guid,
+			{ "Domain GUID", "smb_netlogon.domain.guid", FT_BYTES, BASE_HEX,
+			   NULL, 0x0, "Domain GUID", HFILL }},
+
+		{ &hf_server_ip, {
+			"Server IP", "smb_netlogon.server_ip", FT_IPv4, BASE_NONE,
+			NULL, 0x0, "Server IP Address", HFILL }},
+
+		{ &hf_server_site_name,
+			{ "Server Site Name", "smb_netlogon.server_site_name", FT_STRING, BASE_NONE,
+			  NULL, 0, "SMB NETLOGON Server Site Name", HFILL }},
+
+		{ &hf_client_site_name,
+			{ "Client Site Name", "smb_netlogon.client_site_name", FT_STRING, BASE_NONE,
+			  NULL, 0, "SMB NETLOGON Client Site Name", HFILL }},
 	};
 
 	static gint *ett[] = {


Attachment: ms-compressed-str-01.diff.sig
Description: PGP signature

Attachment: smb-logon-01.diff.sig
Description: PGP signature