patch_netlogon_260709
authorMatthieu Patou <mat+Informatique.Samba@matws.net>
Mon, 27 Jul 2009 08:57:09 +0000 (10:57 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 28 Sep 2009 12:28:47 +0000 (14:28 +0200)
epan/dissectors/packet-dcerpc-lsa.c
epan/dissectors/packet-dcerpc-lsa.h
epan/dissectors/packet-dcerpc-netlogon.c
epan/dissectors/packet-dcerpc-nt.c
epan/dissectors/packet-dcerpc-nt.h
epan/dissectors/packet-dcerpc.c

index ea08b2114bda7ab627a66dab63f28026b4ad349e..b5584e14ce6e2ea6ce8381b99fa773101afede4e 100644 (file)
@@ -3114,7 +3114,16 @@ lsarpc_dissect_struct_lsa_DnsDomainInfo(tvbuff_t *tvb _U_, int offset _U_, packe
                item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, TRUE);
                tree = proto_item_add_subtree(item, ett_lsarpc_lsa_DnsDomainInfo);
        }
-       
+
+  offset = lsarpc_dissect_part_DnsDomainInfo(tvb,offset,pinfo,tree,drep,hf_index,param);
+       proto_item_set_len(item, offset-old_offset);
+
+       return offset;
+}
+/* this part is in NETLOGON_ONE_DOMAIN_INFO struct also*/
+int lsarpc_dissect_part_DnsDomainInfo(tvbuff_t *tvb , int offset, packet_info *pinfo, proto_tree *tree , guint8 *drep,  int hf_index _U_, guint32 param _U_)
+{
+
        offset = lsarpc_dissect_element_lsa_DnsDomainInfo_name(tvb, offset, pinfo, tree, drep);
 
        offset = lsarpc_dissect_element_lsa_DnsDomainInfo_dns_domain(tvb, offset, pinfo, tree, drep);
@@ -3126,8 +3135,6 @@ lsarpc_dissect_struct_lsa_DnsDomainInfo(tvbuff_t *tvb _U_, int offset _U_, packe
        offset = lsarpc_dissect_element_lsa_DnsDomainInfo_sid(tvb, offset, pinfo, tree, drep);
 
 
-       proto_item_set_len(item, offset-old_offset);
-
        return offset;
 }
 
index 9e582b12f4c195c85b261d7d8450913eb94c3c70..636502605f1981cffcbf0a48af534f18453c617b 100644 (file)
@@ -74,6 +74,8 @@ int lsarpc_dissect_struct_lsa_ModificationInfo(tvbuff_t *tvb _U_, int offset _U_
 int lsarpc_dissect_struct_lsa_AuditFullSetInfo(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_);
 int lsarpc_dissect_struct_lsa_AuditFullQueryInfo(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_);
 int lsarpc_dissect_struct_lsa_DnsDomainInfo(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_);
+
+int lsarpc_dissect_part_DnsDomainInfo(tvbuff_t *tvb , int offset, packet_info *pinfo, proto_tree *tree , guint8 *drep , int hf_index _U_, guint32 param _U_);
 #define LSA_POLICY_INFO_AUDIT_LOG (1)
 #define LSA_POLICY_INFO_AUDIT_EVENTS (2)
 #define LSA_POLICY_INFO_DOMAIN (3)
index 6049a41a4290ddf1909bcf6ca9e49c00a697ab22..1598883d4a8707f2610105a97975ddefc06b5e9f 100644 (file)
@@ -28,7 +28,9 @@
 #include "config.h"
 #endif
 
+#include <stdio.h>
 #include <glib.h>
+#include <string.h>
 #include <epan/packet.h>
 #include "packet-dcerpc.h"
 #include "packet-dcerpc-nt.h"
 #include "packet-windows-common.h"
 #include "packet-ntlmssp.h"
 #include "packet-dcerpc-lsa.h"
-
+/* for keytab format */
+#include <epan/asn1.h>
+#include "packet-kerberos.h" 
+/* for decoding */
+#include <epan/crypt/crypt-rc4.h>
+#include <epan/crypt/crypt-md4.h>
+#include <epan/crypt/crypt-md5.h>
+#include <epan/crypt/crypt-des.h>
+
+#define NETLOGON_FLAG_80000000 0x80000000
+#define NETLOGON_FLAG_40000000 0x40000000
+#define NETLOGON_FLAG_20000000 0x20000000
+#define NETLOGON_FLAG_10000000 0x10000000
+#define NETLOGON_FLAG_8000000 0x8000000
+#define NETLOGON_FLAG_4000000 0x4000000
+#define NETLOGON_FLAG_2000000 0x2000000
+#define NETLOGON_FLAG_1000000 0x1000000
+#define NETLOGON_FLAG_800000 0x800000
+#define NETLOGON_FLAG_USEAES 0x400000
+#define NETLOGON_FLAG_200000 0x200000
+#define NETLOGON_FLAG_100000 0x100000
+#define NETLOGON_FLAG_80000 0x80000
+#define NETLOGON_FLAG_40000 0x40000
+#define NETLOGON_FLAG_20000 0x20000
+#define NETLOGON_FLAG_10000 0x10000
+#define NETLOGON_FLAG_8000 0x8000
+#define NETLOGON_FLAG_STRONGKEY 0x4000
+#define NETLOGON_FLAG_2000 0x2000
+#define NETLOGON_FLAG_1000 0x1000
+#define NETLOGON_FLAG_800 0x800
+#define NETLOGON_FLAG_400 0x400
+#define NETLOGON_FLAG_200 0x200
+#define NETLOGON_FLAG_100 0x100
+#define NETLOGON_FLAG_80 0x80
+#define NETLOGON_FLAG_40 0x40
+#define NETLOGON_FLAG_20 0x20
+#define NETLOGON_FLAG_10 0x10
+#define NETLOGON_FLAG_8 0x8
+#define NETLOGON_FLAG_4 0x4
+#define NETLOGON_FLAG_2 0x2
+#define NETLOGON_FLAG_1 0x1
+extern GHashTable *netlogon_auths;
+static int hf_client_challenge = -1;
+static int hf_server_rid = -1;
+static int hf_server_challenge = -1;
+static int hf_client_credential = -1;
+static int hf_server_credential = -1;
 static int proto_dcerpc_netlogon = -1;
+static int hf_netlogon_logon_dnslogondomainname = -1;
+static int hf_netlogon_logon_upn = -1;
 static int hf_netlogon_group_attrs_mandatory = -1;
 static int hf_netlogon_group_attrs_enabled_by_default = -1;
 static int hf_netlogon_group_attrs_enabled = -1;
 static int hf_netlogon_opnum = -1;
+static int hf_netlogon_data_length = -1;
+static int hf_netlogon_extraflags = -1;
+static int hf_netlogon_extra_flags_root_forest = -1;
+static int hf_netlogon_trust_flags_dc_firsthop = -1;
+static int hf_netlogon_trust_flags_rodc_to_dc = -1;
+static int hf_netlogon_trust_flags_rodc_ntlm = -1;
+static int hf_netlogon_package_name = -1;
 static int hf_netlogon_rc = -1;
 static int hf_netlogon_dos_rc = -1;
 static int hf_netlogon_werr_rc = -1;
@@ -52,6 +109,38 @@ static int hf_netlogon_sensitive_data = -1;
 static int hf_netlogon_security_information = -1;
 static int hf_netlogon_dummy = -1;
 static int hf_netlogon_neg_flags = -1;
+static int hf_netlogon_neg_flags_80000000 = -1;
+static int hf_netlogon_neg_flags_40000000 = -1;
+static int hf_netlogon_neg_flags_20000000 = -1;
+static int hf_netlogon_neg_flags_10000000 = -1;
+static int hf_netlogon_neg_flags_8000000 = -1;
+static int hf_netlogon_neg_flags_4000000 = -1;
+static int hf_netlogon_neg_flags_2000000 = -1;
+static int hf_netlogon_neg_flags_1000000 = -1;
+static int hf_netlogon_neg_flags_800000 = -1;
+static int hf_netlogon_neg_flags_400000 = -1;
+static int hf_netlogon_neg_flags_200000 = -1;
+static int hf_netlogon_neg_flags_100000 = -1;
+static int hf_netlogon_neg_flags_80000 = -1;
+static int hf_netlogon_neg_flags_40000 = -1;
+static int hf_netlogon_neg_flags_20000 = -1;
+static int hf_netlogon_neg_flags_10000 = -1;
+static int hf_netlogon_neg_flags_8000 = -1;
+static int hf_netlogon_neg_flags_4000 = -1;
+static int hf_netlogon_neg_flags_2000 = -1;
+static int hf_netlogon_neg_flags_1000 = -1;
+static int hf_netlogon_neg_flags_800 = -1;
+static int hf_netlogon_neg_flags_400 = -1;
+static int hf_netlogon_neg_flags_200 = -1;
+static int hf_netlogon_neg_flags_100 = -1;
+static int hf_netlogon_neg_flags_80 = -1;
+static int hf_netlogon_neg_flags_40 = -1;
+static int hf_netlogon_neg_flags_20 = -1;
+static int hf_netlogon_neg_flags_10 = -1;
+static int hf_netlogon_neg_flags_8 = -1;
+static int hf_netlogon_neg_flags_4 = -1;
+static int hf_netlogon_neg_flags_2 = -1;
+static int hf_netlogon_neg_flags_1 = -1;
 static int hf_netlogon_minworkingsetsize = -1;
 static int hf_netlogon_maxworkingsetsize = -1;
 static int hf_netlogon_pagedpoollimit = -1;
@@ -77,6 +166,9 @@ static int hf_netlogon_pdc_connection_status = -1;
 static int hf_netlogon_tc_connection_status = -1;
 static int hf_netlogon_restart_state = -1;
 static int hf_netlogon_attrs = -1;
+static int hf_netlogon_lsapolicy_len = -1;
+static int hf_netlogon_lsapolicy_referentid = -1;
+static int hf_netlogon_lsapolicy_pointer = -1;
 static int hf_netlogon_count = -1;
 static int hf_netlogon_entries = -1;
 static int hf_netlogon_minpasswdlen = -1;
@@ -94,8 +186,32 @@ static int hf_netlogon_auditing_mode = -1;
 static int hf_netlogon_max_audit_event_count = -1;
 static int hf_netlogon_event_audit_option = -1;
 static int hf_netlogon_unknown_string = -1;
-static int hf_netlogon_unknown_long = -1;
+static int hf_netlogon_trust_extention = -1;
+static int hf_netlogon_trust_max = -1;
+static int hf_netlogon_trust_offset = -1;
+static int hf_netlogon_trust_len = -1;
+static int hf_netlogon_dummy_string = -1;
+static int hf_netlogon_dummy_string2 = -1;
+static int hf_netlogon_dummy_string3 = -1;
+static int hf_netlogon_dummy_string4 = -1;
+static int hf_netlogon_dummy_string5 = -1;
+static int hf_netlogon_dummy_string6 = -1;
+static int hf_netlogon_dummy_string7 = -1;
+static int hf_netlogon_dummy_string8 = -1;
+static int hf_netlogon_dummy_string9 = -1;
+static int hf_netlogon_dummy_string10 = -1;
 static int hf_netlogon_unknown_short = -1;
+static int hf_netlogon_unknown_long = -1;
+static int hf_netlogon_dummy1_long = -1;
+static int hf_netlogon_dummy2_long = -1;
+static int hf_netlogon_dummy3_long = -1;
+static int hf_netlogon_dummy4_long = -1;
+static int hf_netlogon_dummy5_long = -1;
+static int hf_netlogon_dummy6_long = -1;
+static int hf_netlogon_dummy7_long = -1;
+static int hf_netlogon_dummy8_long = -1;
+static int hf_netlogon_dummy9_long = -1;
+static int hf_netlogon_dummy10_long = -1;
 static int hf_netlogon_unknown_char = -1;
 static int hf_netlogon_logon_time = -1;
 static int hf_netlogon_logoff_time = -1;
@@ -131,6 +247,7 @@ static int hf_netlogon_logon_dom = -1;
 static int hf_netlogon_resourcegroupcount = -1;
 static int hf_netlogon_downlevel_domain_name = -1;
 static int hf_netlogon_dns_domain_name = -1;
+static int hf_netlogon_ad_client_dns_name = -1;
 static int hf_netlogon_domain_name = -1;
 static int hf_netlogon_domain_create_time = -1;
 static int hf_netlogon_domain_modify_time = -1;
@@ -142,7 +259,7 @@ static int hf_netlogon_serial_number = -1;
 static int hf_netlogon_num_rids = -1;
 static int hf_netlogon_num_trusts = -1;
 static int hf_netlogon_num_controllers = -1;
-static int hf_netlogon_num_other_groups = -1;
+static int hf_netlogon_num_sid = -1;
 static int hf_netlogon_computer_name = -1;
 static int hf_netlogon_site_name = -1;
 static int hf_netlogon_trusted_dc_name = -1;
@@ -154,7 +271,11 @@ static int hf_netlogon_dc_address_type = -1;
 static int hf_netlogon_client_site_name = -1;
 static int hf_netlogon_workstation = -1;
 static int hf_netlogon_workstation_site_name = -1;
+static int hf_netlogon_os_version = -1;
 static int hf_netlogon_workstation_os = -1;
+static int hf_netlogon_workstation_flags = -1;
+static int hf_netlogon_supportedenctypes = -1;
+
 static int hf_netlogon_workstations = -1;
 static int hf_netlogon_workstation_fqdn = -1;
 static int hf_netlogon_group_name = -1;
@@ -259,6 +380,7 @@ static int hf_netlogon_dc_flags_dns_domain_flag = -1;
 static int hf_netlogon_dc_flags_dns_forest_flag = -1;
 static int hf_netlogon_dnsdomaininfo = -1;
 
+static gint ett_nt_counted_longs_as_string = -1;
 static gint ett_dcerpc_netlogon = -1;
 static gint ett_group_attrs = -1;
 static gint ett_user_flags = -1;
@@ -266,6 +388,7 @@ static gint ett_user_account_control = -1;
 static gint ett_QUOTA_LIMITS = -1;
 static gint ett_IDENTITY_INFO = -1;
 static gint ett_DELTA_ENUM = -1;
+static gint ett_authenticate_flags = -1;
 static gint ett_CYPHER_VALUE = -1;
 static gint ett_UNICODE_MULTI = -1;
 static gint ett_DOMAIN_CONTROLLER_INFO = -1;
@@ -280,12 +403,39 @@ static gint ett_NT_OWF_PASSWORD = -1;
 static gint ett_GROUP_MEMBERSHIP = -1;
 static gint ett_BLOB = -1;
 static gint ett_DS_DOMAIN_TRUSTS = -1;
+static gint ett_LSA_POLICY_INFO = -1;
 static gint ett_DOMAIN_TRUST_INFO = -1;
 static gint ett_trust_flags = -1;
 static gint ett_trust_attribs = -1;
 static gint ett_get_dcname_request_flags = -1;
 static gint ett_dc_flags = -1;
 
+typedef struct _netlogon_auth_vars {
+  guint64 client_challenge;
+  guint64 server_challenge;
+  guint8  session_key[16];
+  guint8  encryption_key[16];
+  guint8  sequence[16];
+  guint32 flags;
+  guint64 seq;
+  guint64 confounder;
+  guint8 private_type;
+  gboolean can_decrypt;
+  void* private;
+} netlogon_auth_vars;
+
+typedef struct _md4_pass {
+    guint8 md4[16];
+} md4_pass;
+
+typedef struct _seen_packet {
+  gboolean isseen;
+  guint32 num;
+} seen_packet;
+
+static seen_packet seen;
+guint
+netlogon_auth_hash (gconstpointer k);
 static e_uuid_t uuid_dcerpc_netlogon = {
         0x12345678, 0x1234, 0xabcd,
         { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0xcf, 0xfb }
@@ -362,6 +512,139 @@ static const true_false_string user_account_control_account_disabled= {
        "This account is DISABLED",
        "This account is NOT disabled",
 };
+
+GHashTable* netlogon_auths = NULL;
+typedef struct _netlogon_auth_key {
+    address src;
+    address dst;
+    guint32 dstport;
+} netlogon_auth_key;
+
+static gint
+netlogon_auth_equal (gconstpointer k1, gconstpointer k2)
+{
+    const netlogon_auth_key *key1 = (const netlogon_auth_key *)k1;
+    const netlogon_auth_key *key2 = (const netlogon_auth_key *)k2;
+    return ((key1->dstport == key2->dstport) && ADDRESSES_EQUAL(&key1->src,&key2->src) &&
+            ADDRESSES_EQUAL(&key1->dst,&key2->dst));
+}
+
+guint
+netlogon_auth_hash (gconstpointer k)
+{
+    const netlogon_auth_key *key1 = (const netlogon_auth_key *)k;
+    guint hash_val1;
+    hash_val1 = key1->dstport;
+    ADD_ADDRESS_TO_HASH(hash_val1, &key1->src);
+    ADD_ADDRESS_TO_HASH(hash_val1, &key1->dst);
+    return hash_val1;
+}
+static int
+netlogon_dissect_EXTRA_FLAGS(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
+{
+       guint32 mask;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+       dcerpc_info *di;
+
+       di=pinfo->private_data;
+       if(di->conformant_run){
+               /*just a run to handle conformant arrays, nothing to dissect */
+               return offset;
+       }
+
+       offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
+                       hf_netlogon_extraflags, &mask);
+
+       if(parent_tree){
+               item = proto_tree_add_uint(parent_tree, hf_netlogon_extraflags, 
+                       tvb, offset-4, 4, mask);
+               tree = proto_item_add_subtree(item, ett_trust_flags);
+       }
+
+       proto_tree_add_boolean(tree, hf_netlogon_extra_flags_root_forest,
+               tvb, offset-4, 4, mask);
+       proto_tree_add_boolean(tree, hf_netlogon_trust_flags_dc_firsthop,
+               tvb, offset-4, 4, mask);
+       proto_tree_add_boolean(tree, hf_netlogon_trust_flags_rodc_to_dc,
+               tvb, offset-4, 4, mask);
+       proto_tree_add_boolean(tree, hf_netlogon_trust_flags_rodc_ntlm,
+               tvb, offset-4, 4, mask);
+
+       return offset;
+}
+int
+dissect_ndr_lm_nt_hash_cb(tvbuff_t *tvb, int offset,
+            packet_info *pinfo, proto_tree *tree,
+            guint8 *drep, int hf_index,
+            dcerpc_callback_fnct_t *callback,
+            void *callback_args)
+{
+  dcerpc_info *di = pinfo->private_data;
+  guint16 len, size;
+
+  /* Structure starts with short, but is aligned for longs */
+
+  ALIGN_TO_4_BYTES;
+
+  if (di->conformant_run)
+    return offset;
+
+  /*
+           struct {
+               short len;
+               short size;
+               [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
+           } HASH;
+
+  */
+
+  offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+      hf_nt_cs_len, &len);
+
+  offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+      hf_nt_cs_size, &size);
+
+  offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, tree, drep,
+      dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
+      "Bytes Array", hf_index, callback, callback_args);
+
+  return offset;
+}
+static int
+dissect_ndr_lm_nt_hash_helper(tvbuff_t *tvb, int offset,
+          packet_info *pinfo, proto_tree *tree,
+          guint8 *drep, int hf_index, int levels _U_,
+          gboolean add_subtree)
+{
+  proto_item *item;
+  proto_tree *subtree = tree;
+
+  if (add_subtree) {
+
+    item = proto_tree_add_text(
+      tree, tvb, offset, 0, "%s",
+      proto_registrar_get_name(hf_index));
+
+    subtree = proto_item_add_subtree(item,ett_LM_OWF_PASSWORD);
+  }
+
+  return dissect_ndr_lm_nt_hash_cb(
+    tvb, offset, pinfo, subtree, drep, hf_index,
+    NULL, NULL);
+    /*cb_wstr_postprocess, GINT_TO_POINTER(2 + levels));*/
+} 
+static void printnbyte(const guint8* tab,int nb,char* txt,char* txt2)
+{
+  int i=0;
+  fprintf(stderr,"%s ",txt);
+  for(i=0;i<nb;i++)
+  {
+    fprintf(stderr,"%02hhX ",*(tab+i));
+  }
+  fprintf(stderr,"%s",txt2);
+}
 static int
 netlogon_dissect_USER_ACCOUNT_CONTROL(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
@@ -620,6 +903,28 @@ netlogon_dissect_netrlogonuaslogoff_reply(tvbuff_t *tvb, int offset,
        return offset;
 }
 
+static int
+netlogon_dissect_BYTE_byte(tvbuff_t *tvb, int offset,
+                       packet_info *pinfo, proto_tree *tree,
+                       guint8 *drep)
+{
+               offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_unknown_char, NULL);
+
+       return offset;
+}
+
+static int
+netlogon_dissect_BYTE_array(tvbuff_t *tvb, int offset,
+                       packet_info *pinfo, proto_tree *tree,
+                       guint8 *drep)
+{
+       offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_BYTE_byte);
+
+       return offset;
+}
+
 
 
 
@@ -659,8 +964,8 @@ netlogon_dissect_LOGON_IDENTITY_INFO(tvbuff_t *tvb, int offset,
        offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, drep,
                hf_netlogon_logon_id, NULL);
 
-       offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_acct_name, CB_STR_COL_INFO|3);
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_acct_name, 1);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
                hf_netlogon_workstation, 0);
@@ -804,49 +1109,91 @@ netlogon_dissect_CHALLENGE(tvbuff_t *tvb, int offset,
  * IDL   STRING lmchallengeresponse;
  * IDL } NETWORK_INFO;
  */
-
+/*
 static void dissect_nt_chal_resp_cb(packet_info *pinfo _U_, proto_tree *tree, 
                                    proto_item *item _U_, tvbuff_t *tvb, 
                                    int start_offset, int end_offset, 
-                                   void *callback_args _U_)
+                                   void *callback_args )
 {
        int len;
+  gint options = GPOINTER_TO_INT(callback_args);
+  gint levels = CB_STR_ITEM_LEVELS(options);
+  char *s;
 
-       /* Skip over 3 guint32's in NDR format */
+
+       / * Skip over 3 guint32's in NDR format * /
 
        if (start_offset % 4)
                start_offset += 4 - (start_offset % 4);
 
        start_offset += 12;
        len = end_offset - start_offset;
-
-       /* Call ntlmv2 response dissector */
+  
+  s = tvb_bytes_to_str(
+    tvb, start_offset , len  );
+
+  / * Append string to upper-level proto_items * /
+
+  if (levels > 0 && item && s && s[0]) {
+    proto_item_append_text(item, ": %s", s);
+    item = item->parent;
+    levels--;
+    if (levels > 0) {
+      proto_item_append_text(item, ": %s", s);
+      item = item->parent;
+      levels--;
+      while (levels > 0) {
+        proto_item_append_text(item, " %s", s);
+        item = item->parent;
+        levels--;
+      }
+    }
+  }
+       / * Call ntlmv2 response dissector   * /
 
        if (len > 24)
                dissect_ntlmv2_response(tvb, tree, start_offset, len);
 }
-
+*/
 static int
 netlogon_dissect_NETWORK_INFO(tvbuff_t *tvb, int offset,
                packet_info *pinfo, proto_tree *tree,
                guint8 *drep)
 {
+
        offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
                pinfo, tree, drep);
-
        offset = netlogon_dissect_CHALLENGE(tvb, offset,
                pinfo, tree, drep);
+/*
+       offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+               NDR_POINTER_UNIQUE, "NT ", 
+               hf_netlogon_nt_owf_password, 0);
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_data_length, NULL);*/
+  offset = dissect_ndr_lm_nt_hash_helper(tvb,offset,pinfo, tree, drep, hf_netlogon_lm_chal_resp, 0,TRUE);
+  offset = dissect_ndr_lm_nt_hash_helper(tvb,offset,pinfo, tree, drep, hf_netlogon_lm_chal_resp, 0,TRUE);
+ /* Not really sure that it really works with NTLM v2 ....*/
+   /* 
+       offset = netlogon_dissect_LM_OWF_PASSWORD(tvb, offset,
+               pinfo, tree, drep);
 
-       offset = dissect_ndr_counted_byte_array_cb(
+       offset = netlogon_dissect_NT_OWF_PASSWORD(tvb, offset,
+               pinfo, tree, drep);
+*/
+       return offset;
+       /*offset = dissect_ndr_counted_byte_array_cb( 
                tvb, offset, pinfo, tree, drep, hf_netlogon_nt_chal_resp,
-               dissect_nt_chal_resp_cb, NULL);
+    dissect_nt_chal_resp_cb,GINT_TO_POINTER(2));
+               hf_netlogon_nt_chal_resp, 0);
 
        offset = dissect_ndr_counted_byte_array(tvb, offset, pinfo, tree, drep,
                hf_netlogon_lm_chal_resp, 0);
 
-       return offset;
+       return offset;*/
 }
 
+
 /*
  * IDL typedef struct {
  * IDL   LOGON_IDENTITY_INFO logon_info;
@@ -870,7 +1217,30 @@ netlogon_dissect_SERVICE_INFO(tvbuff_t *tvb, int offset,
 
        return offset;
 }
+static int
+netlogon_dissect_GENERIC_INFO(tvbuff_t *tvb, int offset,
+               packet_info *pinfo, proto_tree *tree,
+               guint8 *drep)
+{
+  dcerpc_info *di;
+  dcerpc_call_value *dcv;
+  di=pinfo->private_data;
+  dcv = (dcerpc_call_value *)di->call_data;
+       offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
+               pinfo, tree, drep);
+
+       offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_package_name, 0|CB_STR_SAVE);
 
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_data_length, NULL);
+
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_BYTE_array, NDR_POINTER_REF,
+               "Logon Data", -1);
+       return offset;
+}
 /*
  * IDL typedef [switch_type(short)] union {
  * IDL    [case(1)][unique] INTERACTIVE_INFO *iinfo;
@@ -887,7 +1257,6 @@ netlogon_dissect_LEVEL(tvbuff_t *tvb, int offset,
 
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
                hf_netlogon_level16, &level);
-
        ALIGN_TO_4_BYTES;
        switch(level){
        case 1:
@@ -904,9 +1273,27 @@ netlogon_dissect_LEVEL(tvbuff_t *tvb, int offset,
                offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        netlogon_dissect_SERVICE_INFO, NDR_POINTER_UNIQUE,
                        "SERVICE_INFO:", -1);
+       case 4:
+               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       netlogon_dissect_GENERIC_INFO, NDR_POINTER_UNIQUE,
+                       "GENERIC_INFO:", -1);
+               break;
+       case 5:
+               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       netlogon_dissect_INTERACTIVE_INFO, NDR_POINTER_UNIQUE,
+                       "INTERACTIVE_TRANSITIVE_INFO:", -1);
+               break;
+       case 6:
+               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       netlogon_dissect_NETWORK_INFO, NDR_POINTER_UNIQUE,
+                       "NETWORK_TRANSITIVE_INFO", -1);
+               break;
+       case 7:
+               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       netlogon_dissect_SERVICE_INFO, NDR_POINTER_UNIQUE,
+                       "SERVICE_TRANSITIVE_INFO", -1);
                break;
        }
-
        return offset;
 }
 
@@ -1164,7 +1551,6 @@ netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
                packet_info *pinfo, proto_tree *tree,
                guint8 *drep)
 {
-       int i;
 
        offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
                hf_netlogon_logon_time);
@@ -1217,7 +1603,7 @@ netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_netlogon_num_rids, NULL);
 
-        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
                "GROUP_MEMBERSHIP_ARRAY", -1);
 
@@ -1235,17 +1621,35 @@ netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
 
        offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, drep);
 
-       for(i=0;i<2;i++){
-               offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-                       hf_netlogon_unknown_long, NULL);
-       }
+  offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy1_long, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy2_long, NULL);
+
        offset = netlogon_dissect_USER_ACCOUNT_CONTROL(tvb, offset,
                        pinfo, tree, drep);
 
-       for(i=0;i<7;i++){
-               offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-                       hf_netlogon_unknown_long, NULL);
-       }
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy4_long, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy5_long, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy6_long, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy7_long, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy8_long, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy9_long, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_netlogon_dummy10_long, NULL);
 
        return offset;
 }
@@ -1289,6 +1693,8 @@ netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
                        guint8 *drep)
 {
+  offset = netlogon_dissect_VALIDATION_SAM_INFO(tvb,offset,pinfo,tree,drep);
+  /*
        int i;
 
        offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
@@ -1342,7 +1748,7 @@ netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_netlogon_num_rids, NULL);
 
-        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
                "GROUP_MEMBERSHIP_ARRAY", -1);
 
@@ -1371,11 +1777,11 @@ netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
                offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                        hf_netlogon_unknown_long, NULL);
        }
-
+*/
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_num_other_groups, NULL);
+               hf_netlogon_num_sid, NULL);
 
-        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
                "SID_AND_ATTRIBUTES_ARRAY:", -1);
 
@@ -1383,9 +1789,50 @@ netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
 }
 
 
+static int
+netlogon_dissect_VALIDATION_SAM_INFO4(tvbuff_t *tvb, int offset,
+                       packet_info *pinfo, proto_tree *tree,
+                       guint8 *drep)
+{
+  offset = netlogon_dissect_VALIDATION_SAM_INFO2(tvb,offset,pinfo,tree,drep);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_logon_dnslogondomainname, 0);
 
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_logon_upn, 0);
 
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string, 0);
 
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string2, 0);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string3, 0);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string4, 0);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string5, 0);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string6, 0);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string7, 0);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string8, 0);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string9, 0);
+
+  offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_dummy_string10, 0);
+  return offset;
+}
 /*
  * IDL typedef struct {
  * IDL   uint64 LogonTime;
@@ -1426,8 +1873,9 @@ netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
                        guint8 *drep)
 {
-       int i;
        guint32 rgc;
+  offset = netlogon_dissect_VALIDATION_SAM_INFO(tvb,offset,pinfo,tree,drep);
+       /*int i;
 
        offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
                hf_netlogon_logon_time);
@@ -1480,7 +1928,7 @@ netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_netlogon_num_rids, NULL);
 
-        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
                "GROUP_MEMBERSHIP_ARRAY", -1);
 
@@ -1508,14 +1956,15 @@ netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
        for(i=0;i<7;i++){
                offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                        hf_netlogon_unknown_long, NULL);
-       }
+       }*/
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_num_other_groups, NULL);
+               hf_netlogon_num_sid, NULL);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
                "SID_AND_ATTRIBUTES_ARRAY:", -1);
+  
 
        offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, drep);
 
@@ -1568,7 +2017,7 @@ netlogon_dissect_PAC_CONSTRAINED_DELEGATION(tvbuff_t *tvb, int offset,
 
        return offset;
 }
-
+/*
 static int
 netlogon_dissect_PAC(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
@@ -1579,7 +2028,6 @@ netlogon_dissect_PAC(tvbuff_t *tvb, int offset,
 
        di=pinfo->private_data;
        if(di->conformant_run){
-               /*just a run to handle conformant arrays, nothing to dissect */
                return offset;
        }
 
@@ -1603,7 +2051,6 @@ netlogon_dissect_AUTH(tvbuff_t *tvb, int offset,
 
        di=pinfo->private_data;
        if(di->conformant_run){
-               /*just a run to handle conformant arrays, nothing to dissect */
                return offset;
        }
 
@@ -1616,8 +2063,21 @@ netlogon_dissect_AUTH(tvbuff_t *tvb, int offset,
 
        return offset;
 }
+*/  
+static int
+netlogon_dissect_VALIDATION_GENERIC_INFO2 (tvbuff_t *tvb, int offset,
+                       packet_info *pinfo, proto_tree *tree,
+                       guint8 *drep)
+{
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_data_length, NULL);
 
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_BYTE_array, NDR_POINTER_REF,
+               "Validation Data", -1);
 
+ return offset;
+}
 /*
  * IDL typedef struct {
  * IDL   long pac_size
@@ -1637,6 +2097,7 @@ netlogon_dissect_AUTH(tvbuff_t *tvb, int offset,
  * IDL   UNICODESTRING dummy4;
  * IDL } VALIDATION_PAC_INFO;
  */
+/* Not used (anymore ?)
 static int
 netlogon_dissect_VALIDATION_PAC_INFO(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
@@ -1694,14 +2155,16 @@ netlogon_dissect_VALIDATION_PAC_INFO(tvbuff_t *tvb, int offset,
 
        return offset;
 }
-
-
+*/
 /*
  * IDL typedef [switch_type(short)] union {
+ * IDL    [case(1)][unique] VALIDATION_UAS *uas;
  * IDL    [case(2)][unique] VALIDATION_SAM_INFO *sam;
  * IDL    [case(3)][unique] VALIDATION_SAM_INFO2 *sam2;
- * IDL    [case(4)][unique] VALIDATION_PAC_INFO *pac;
- * IDL    [case(5)][unique] VALIDATION_PAC_INFO *pac2;
+ * IDL    [case(4)][unique] VALIDATION_GENERIC_INFO *generic;
+ * IDL    [case(5)][unique] VALIDATION_GENERIC_INFO *generic2;
+ * IDL    [case(5)][unique] VALIDATION_GENERIC_INFO *generic2;
+ * IDL    [case(6)][unique] VALIDATION_SAM_INFO4 *sam4;
  * IDL } VALIDATION;
  */
 static int
@@ -1716,6 +2179,11 @@ netlogon_dissect_VALIDATION(tvbuff_t *tvb, int offset,
 
        ALIGN_TO_4_BYTES;
        switch(level){
+       case 1:
+               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       netlogon_dissect_VALIDATION_UAS_INFO, NDR_POINTER_UNIQUE,
+                       "VALIDATION_UAS_INFO:", -1);
+               break;
        case 2:
                offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        netlogon_dissect_VALIDATION_SAM_INFO, NDR_POINTER_UNIQUE,
@@ -1728,20 +2196,95 @@ netlogon_dissect_VALIDATION(tvbuff_t *tvb, int offset,
                break;
        case 4:
                offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-                       netlogon_dissect_VALIDATION_PAC_INFO, NDR_POINTER_UNIQUE,
-                       "VALIDATION_PAC_INFO:", -1);
+                       netlogon_dissect_VALIDATION_GENERIC_INFO2, NDR_POINTER_UNIQUE,
+                       "VALIDATION_INFO:", -1);
                break;
        case 5:
                offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-                       netlogon_dissect_VALIDATION_PAC_INFO, NDR_POINTER_UNIQUE,
-                       "VALIDATION_PAC_INFO:", -1);
+                       netlogon_dissect_VALIDATION_GENERIC_INFO2, NDR_POINTER_UNIQUE,
+                       "VALIDATION_INFO2:", -1);
+               break;
+       case 6:
+               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       netlogon_dissect_VALIDATION_SAM_INFO4, NDR_POINTER_UNIQUE,
+                       "VALIDATION_SAM_INFO4:", -1);
                break;
        }
+       return offset;
+}
+/*
+ * IDL long NetrLogonSamLogonWithFlags(
+ * IDL      [in][unique][string] wchar_t *ServerName,
+ * IDL      [in][unique][string] wchar_t *Workstation,
+ * IDL      [in][unique] AUTHENTICATOR *credential,
+ * IDL      [in][out][unique] AUTHENTICATOR *returnauthenticator,
+ * IDL      [in] short LogonLevel,
+ * IDL      [in][ref] LOGON_LEVEL *logonlevel,
+ * IDL      [in] short ValidationLevel,
+ * IDL      [out][ref] VALIDATION *validation,
+ * IDL      [out][ref] boolean Authorative
+ * IDL      [in][out] unsigned long ExtraFlags 
+ * IDL );
+ */
+static int
+netlogon_dissect_netrlogonsamlogonflags_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+       offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+               NDR_POINTER_UNIQUE, "Computer Name", 
+               hf_netlogon_computer_name, 0);
+
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
+               "AUTHENTICATOR: credential", -1);
+
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
+               "AUTHENTICATOR: return_authenticator", -1);
+
+       offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_level16, NULL);
+
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_LEVEL, NDR_POINTER_REF,
+               "LEVEL: LogonLevel", -1);
+
+       offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_validation_level, NULL);
+       
+  offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, drep);
+
+       return offset;
+}
+
+static int
+netlogon_dissect_netrlogonsamlogonflags_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
+               "AUTHENTICATOR: return_authenticator", -1);
+
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_VALIDATION, NDR_POINTER_REF,
+               "VALIDATION:", -1);
+
+       offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_authoritative, NULL);
+  
+  offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, drep);
+
+       offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+                                 hf_netlogon_rc, NULL);
 
        return offset;
 }
 
 
+
 /*
  * IDL long NetrLogonSamLogon(
  * IDL      [in][unique][string] wchar_t *ServerName,
@@ -1862,6 +2405,20 @@ netlogon_dissect_netrlogonsamlogoff_reply(tvbuff_t *tvb, int offset,
        return offset;
 }
 
+static void generate_hash_key(packet_info *pinfo,unsigned char is_server,netlogon_auth_key *key)
+{
+  if(is_server) {
+    key->dstport = pinfo->srcport;
+    COPY_ADDRESS(&key->dst,&pinfo->src);
+    COPY_ADDRESS(&key->src,&pinfo->dst);
+  }
+  else {
+    COPY_ADDRESS(&key->dst,&pinfo->dst);
+    COPY_ADDRESS(&key->src,&pinfo->src);
+    key->dstport = pinfo->destport;
+  }
+
+} 
 
 /*
  * IDL long NetrServerReqChallenge(
@@ -1875,32 +2432,59 @@ static int
 netlogon_dissect_netrserverreqchallenge_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, guint8 *drep)
 {
+  /*int oldoffset = offset;*/
+  netlogon_auth_vars *vars;
+  netlogon_auth_key *key = se_alloc(sizeof(netlogon_auth_key));
+  guint8 tab[8] = { 0,0,0,0,0,0,0,0};
+
+  vars = se_alloc(sizeof(netlogon_auth_vars));
        offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
                pinfo, tree, drep);
-
        offset = dissect_ndr_pointer_cb(
                tvb, offset, pinfo, tree, drep, 
                dissect_ndr_wchar_cvstring, NDR_POINTER_REF, 
                "Computer Name", hf_netlogon_computer_name, 
                cb_wstr_postprocess, 
                GINT_TO_POINTER(CB_STR_COL_INFO | 1));
+       offset = dissect_dcerpc_uint64(tvb, offset, pinfo, tree, drep,
+               hf_client_challenge,&vars->client_challenge);
+  memcpy(tab,&vars->client_challenge,8);
 
-       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-               netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
-               "CREDENTIAL: client challenge", -1);
+  generate_hash_key(pinfo,0,key);
+  if (!g_hash_table_lookup(netlogon_auths, key))
+  {
+    g_hash_table_insert(netlogon_auths,(gconstpointer*) key,vars);
+  }
 
        return offset;
 }
+
 static int
 netlogon_dissect_netrserverreqchallenge_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, guint8 *drep)
 {
-       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+  netlogon_auth_vars *vars;
+  netlogon_auth_key key;
+  guint64 server_challenge;
+
+  generate_hash_key(pinfo,1,&key);
+  vars = g_hash_table_lookup(netlogon_auths,(gconstpointer*) &key);
+  
+       offset = dissect_dcerpc_uint64(tvb, offset, pinfo, tree, drep,
+               hf_server_challenge, &server_challenge);
+       /*offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
-               "CREDENTIAL: server credential", -1);
+               "CREDENTIAL: server credential", -1);*/
 
        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
                                  hf_netlogon_rc, NULL);
+  if(vars != NULL) {
+    vars->server_challenge = server_challenge;
+  }
+  else 
+  {
+    fprintf(stderr,"Not found in challenge reply\n");
+  }
 
        return offset;
 }
@@ -3765,28 +4349,6 @@ netlogon_dissect_UAS_INFO_0(tvbuff_t *tvb, int offset,
 }
 
 
-static int
-netlogon_dissect_BYTE_byte(tvbuff_t *tvb, int offset,
-                       packet_info *pinfo, proto_tree *tree,
-                       guint8 *drep)
-{
-               offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
-                       hf_netlogon_unknown_char, NULL);
-
-       return offset;
-}
-
-static int
-netlogon_dissect_BYTE_array(tvbuff_t *tvb, int offset,
-                       packet_info *pinfo, proto_tree *tree,
-                       guint8 *drep)
-{
-       offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
-               netlogon_dissect_BYTE_byte);
-
-       return offset;
-}
-
 /*
  * IDL long NetrAccountDeltas(
  * IDL      [in][string][unique] wchar_t *logonserver,
@@ -4510,10 +5072,10 @@ netlogon_dissect_netrlogoncontrol2ex_reply(tvbuff_t *tvb, int offset,
 
 
 static const value_string trust_type_vals[] = {
-       { 1,                            "DOWNLEVEL" },
-       { 2,                            "UPLEVEL" },
-       { 3,                            "MIT" },
-       { 4,                            "DCE" },
+       { 1,                            "NT4 Domain" },
+       { 2,                            "AD Domain" },
+       { 3,                            "MIT Kerberos realm" },
+       { 4,                            "DCE realm" },
        { 0, NULL }
 };
 
@@ -4526,6 +5088,11 @@ static const value_string dc_address_types[] = {
 };
 
 
+#define RQ_ROOT_FOREST         0x0001
+#define RQ_DC_XFOREST  0x0002
+#define RQ_RODC_DIF_DOMAIN             0x0004
+#define RQ_NTLM_FROM_RODC              0x0008
+
 #define DS_DOMAIN_IN_FOREST            0x0001
 #define DS_DOMAIN_DIRECT_OUTBOUND      0x0002
 #define DS_DOMAIN_TREE_ROOT            0x0004
@@ -4556,6 +5123,8 @@ static const true_false_string trust_tree_root = {
        "The domain is the ROOT of a domain TREE",
        "The domain is NOT a root of a domain tree"
 };
+
 static int
 netlogon_dissect_DOMAIN_TRUST_FLAGS(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
@@ -4953,7 +5522,7 @@ netlogon_dissect_pointer_long(tvbuff_t *tvb, int offset,
                                      di->hf_index, NULL);
        return offset;
 }
-
+/*
 static int
 netlogon_dissect_pointer_char(tvbuff_t *tvb, int offset,
                              packet_info *pinfo, proto_tree *tree,
@@ -4966,7 +5535,7 @@ netlogon_dissect_pointer_char(tvbuff_t *tvb, int offset,
                                      di->hf_index, NULL);
        return offset;
 }
-
+*/
 static int
 netlogon_dissect_UNICODE_MULTI_byte(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
@@ -5053,11 +5622,50 @@ netlogon_dissect_DOMAIN_CONTROLLER_INFO(tvbuff_t *tvb, int offset,
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
                NDR_POINTER_UNIQUE, "DC Site", hf_netlogon_dc_site_name, 0);
 
-       offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
-               NDR_POINTER_UNIQUE, "Client Site", 
-               hf_netlogon_client_site_name, 0);
+       offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+               NDR_POINTER_UNIQUE, "Client Site", 
+               hf_netlogon_client_site_name, 0);
+
+       proto_item_set_len(item, offset-old_offset);
+       return offset;
+}
+
+
+
+static int
+dissect_ndr_trust_extension(tvbuff_t *tvb, int offset,
+                       packet_info *pinfo, proto_tree *tree,
+                       guint8 *drep)
+{
+       guint32 len,max;
+       dcerpc_info *di;
+
+       di=pinfo->private_data;
+       if(di->conformant_run){
+               return offset;
+       }
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_trust_max, &max);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_trust_offset, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_trust_len, &len);
+
+  if( max * 2 == 16 ) {
+    offset = netlogon_dissect_DOMAIN_TRUST_FLAGS(tvb, offset, pinfo, tree, drep);
+
+    offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+      hf_netlogon_trust_parent_index, NULL);
+
+    offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+      hf_netlogon_trust_type, NULL);
+
+    offset = netlogon_dissect_DOMAIN_TRUST_ATTRIBS(tvb, offset, pinfo, tree, drep);
+  } 
+  /* else do something scream shout .... */
 
-       proto_item_set_len(item, offset-old_offset);
        return offset;
 }
 
@@ -5071,7 +5679,6 @@ netlogon_dissect_BLOB_array(tvbuff_t *tvb, int offset,
 
        di=pinfo->private_data;
        if(di->conformant_run){
-               /*just a run to handle conformant arrays, nothing to dissect.*/
                return offset;
        }
 
@@ -5084,33 +5691,51 @@ netlogon_dissect_BLOB_array(tvbuff_t *tvb, int offset,
 
        return offset;
 }
-
-static int
-netlogon_dissect_BLOB(tvbuff_t *tvb, int offset,
-                       packet_info *pinfo, proto_tree *parent_tree,
-                       guint8 *drep)
-{
-       proto_item *item=NULL;
-       proto_tree *tree=NULL;
-
-       if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, 0,
-                       "BLOB:");
-               tree = proto_item_add_subtree(item, ett_BLOB);
-       }
-
-       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_blob_size, NULL);
-
-       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-               netlogon_dissect_BLOB_array, NDR_POINTER_UNIQUE,
-               "BLOB:", -1);
-
-       return offset;
-}
-
-static int
-netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t *tvb, int offset,
+int
+dissect_ndr_ulongs_as_counted_string(tvbuff_t *tvb, int offset,
+            packet_info *pinfo, proto_tree *tree,
+            guint8 *drep, int hf_index)
+{
+  dcerpc_info *di = pinfo->private_data;
+  guint16 len, size;
+  gboolean add_subtree = TRUE; /* Manage room for evolution*/
+  proto_item *item;
+  proto_tree *subtree = tree;
+
+  if (add_subtree) {
+
+    item = proto_tree_add_text(
+      tree, tvb, offset, 0, "%s",
+      proto_registrar_get_name(hf_index));
+
+    subtree = proto_item_add_subtree(item, ett_nt_counted_longs_as_string);
+  }
+  /* Structure starts with short, but is aligned for longs */
+  ALIGN_TO_4_BYTES;
+
+  if (di->conformant_run)
+    return offset;
+
+  /*
+           struct {
+               short len;
+               short size;
+               [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
+           } UNICODE_STRING;
+
+   */
+
+  offset = dissect_ndr_uint16(tvb, offset, pinfo, subtree, drep,
+      hf_nt_cs_len, &len);
+  offset = dissect_ndr_uint16(tvb, offset, pinfo, subtree, drep,
+      hf_nt_cs_size, &size);
+  offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, subtree, drep,
+      dissect_ndr_trust_extension, NDR_POINTER_UNIQUE,
+      "Buffer", hf_index,NULL,NULL);
+  return offset;
+}
+static int
+netlogon_dissect_ONE_DOMAIN_INFO(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *parent_tree,
                        guint8 *drep)
 {
@@ -5120,62 +5745,100 @@ netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t *tvb, int offset,
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 0,
-                       "DOMAIN_TRUST_INFO:");
+                       "ONE_DOMAIN_INFO");
                tree = proto_item_add_subtree(item, ett_DOMAIN_TRUST_INFO);
        }
+/*hf_netlogon_dnsdomaininfo*/
+       offset = lsarpc_dissect_part_DnsDomainInfo(tvb, offset, pinfo, tree, drep, 0, 0);
 
 
-       offset = lsarpc_dissect_struct_lsa_DnsDomainInfo(tvb, offset, pinfo, tree, drep, hf_netlogon_dnsdomaininfo, 0);
-
-
-       /* Guesses at best. */
-       offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+       /* It is structed as a string but it's not ... it's 4 ulong */
+       offset = dissect_ndr_ulongs_as_counted_string(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_trust_extention);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_dummy_string2, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_dummy_string3, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_dummy_string4, 0);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_dummy1_long, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_dummy2_long, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_dummy3_long, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_dummy4_long, NULL);
 
        proto_item_set_len(item, offset-old_offset);
        return offset;
 }
 
 static int
-netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY(tvbuff_t *tvb, int offset,
+netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
                        guint8 *drep)
 {
        offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
-               netlogon_dissect_DOMAIN_TRUST_INFO);
+               netlogon_dissect_ONE_DOMAIN_INFO);
 
        return offset;
 }
 
+  
 static int
-netlogon_dissect_DOMAIN_QUERY_1(tvbuff_t *tvb, int offset,
-                       packet_info *pinfo, proto_tree *tree,
-                       guint8 *drep)
+netlogon_dissect_LSA_POLICY_INFO(tvbuff_t *tvb _U_, int offset,
+                       packet_info *pinfo _U_, proto_tree *tree _U_,
+                       guint8 *drep _U_ )
 {
-       offset = netlogon_dissect_BLOB(tvb, offset,
-               pinfo, tree, drep);
+       proto_item *item=NULL;
+       proto_tree *subtree=NULL;
+  guint32 len;
+       dcerpc_info *di;
+
+       di=pinfo->private_data;
+       if(di->conformant_run){
+               return offset;
+       }
+
+       if(tree){
+         item = proto_tree_add_text(tree, tvb, offset, 0,
+                       "LSA Policy");
+         subtree = proto_item_add_subtree(item, ett_LSA_POLICY_INFO);
+       }
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, drep,
+               hf_netlogon_lsapolicy_len, &len);
+
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, subtree, drep,
+               netlogon_dissect_BLOB_array, NDR_POINTER_UNIQUE,
+               "Pointer:", -1);
+
+  return offset;
+}
 
+
+
+
+static int
+netlogon_dissect_WORKSTATION_INFO(tvbuff_t *tvb , int offset ,
+                       packet_info *pinfo , proto_tree *tree ,
+                       guint8 *drep )
+{
+  /* This is not the good way to do it ... it stinks ...
+   * but after half of a day fighting against wireshark and ndr ... 
+   * I decided to keep this hack ... 
+   * At least data are correctly displayed without invented ints ...
+   */
+       offset = netlogon_dissect_LSA_POLICY_INFO(tvb, offset,
+               pinfo, tree, drep);
+  
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
                NDR_POINTER_UNIQUE, "Workstation FQDN", 
                hf_netlogon_workstation_fqdn, 0);
@@ -5185,96 +5848,106 @@ netlogon_dissect_DOMAIN_QUERY_1(tvbuff_t *tvb, int offset,
                hf_netlogon_workstation_site_name, 0);
 
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
-               NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
-
-       offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
-               NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
+               NDR_POINTER_UNIQUE, "Dummy 1", hf_netlogon_dummy_string, 0);
+       
+  offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+               NDR_POINTER_UNIQUE, "Dummy 2", hf_netlogon_dummy_string2, 0);
 
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
-               NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
+               NDR_POINTER_UNIQUE, "Dummy 3", hf_netlogon_dummy_string3, 0);
 
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
-               NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
+               NDR_POINTER_UNIQUE, "Dummy 4", hf_netlogon_dummy_string4, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_os_version, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
                hf_netlogon_workstation_os, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_dummy_string3, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_dummy_string4, 0);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_workstation_flags, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_dummy2_long, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_dummy3_long, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
-
-       return offset;
+               hf_netlogon_dummy4_long, NULL);
+  return offset;
 }
 
+static int 
+netlogon_dissect_WORKSTATION_INFORMATION(tvbuff_t *tvb , int offset ,
+                       packet_info *pinfo , proto_tree *tree ,
+                       guint8 *drep ) {
+
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_WORKSTATION_INFO, NDR_POINTER_UNIQUE,
+               "WORKSTATION INFO", -1);
+  return offset;
+}  
 static int
-netlogon_dissect_DOMAIN_INFO_1(tvbuff_t *tvb, int offset,
+netlogon_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
                        guint8 *drep)
 {
-       offset = netlogon_dissect_DOMAIN_TRUST_INFO(tvb, offset, pinfo, tree, drep);
+       offset = netlogon_dissect_ONE_DOMAIN_INFO(tvb, offset, pinfo, tree, drep);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_netlogon_num_trusts, NULL);
 
-        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-               netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY, NDR_POINTER_UNIQUE,
-               "DOMAIN_TRUST_ARRAY: Trusts", -1);
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_DOMAIN_TRUST_INFO, NDR_POINTER_UNIQUE,
+               "DOMAIN_TRUST_ARRAY: Trusted domains", -1);
+    
+  offset = netlogon_dissect_LSA_POLICY_INFO(tvb,offset,pinfo, tree,drep);
 
-       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+/*     offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_netlogon_num_trusts, NULL);
 
-        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-               netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY, NDR_POINTER_UNIQUE,
-               "DOMAIN_TRUST_ARRAY:", -1);
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_DOMAIN_TRUST_INFO, NDR_POINTER_UNIQUE,
+               "LSA Policy", -1);
+*/ 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_dns_domain_name, 0);
+               hf_netlogon_ad_client_dns_name, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_dummy_string2, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_dummy_string3, 0);
 
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_string, 0);
+               hf_netlogon_dummy_string4, 0);
 
-       /* These four integers appear to mirror the last four in the query. */
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_workstation_flags, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_supportedenctypes, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_dummy3_long, NULL);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               hf_netlogon_dummy4_long, NULL);
 
        return offset;
 }
 
 
 static int
-netlogon_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
+netlogon_dissect_DOMAIN_INFORMATION(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
                        guint8 *drep)
 {
@@ -5287,8 +5960,8 @@ netlogon_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
        switch(level){
        case 1:
                offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-                       netlogon_dissect_DOMAIN_INFO_1, NDR_POINTER_UNIQUE,
-                       "DOMAIN_INFO_1:", -1);
+                       netlogon_dissect_DOMAIN_INFO, NDR_POINTER_UNIQUE,
+                       "DOMAIN_INFO", -1);
                break;
        }
 
@@ -5556,8 +6229,8 @@ netlogon_dissect_TYPE_44(tvbuff_t *tvb, int offset,
        return offset;
 }
 
-static int
-netlogon_dissect_DOMAIN_QUERY(tvbuff_t *tvb, int offset,
+ static int
+netlogon_dissect_WORKSTATION_BUFFER(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *tree,
                        guint8 *drep)
 {
@@ -5565,21 +6238,22 @@ netlogon_dissect_DOMAIN_QUERY(tvbuff_t *tvb, int offset,
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_netlogon_level, &level);
-
-       ALIGN_TO_4_BYTES;
-       switch(level){
-       case 1:
-               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-                       netlogon_dissect_DOMAIN_QUERY_1, NDR_POINTER_UNIQUE,
-                       "DOMAIN_QUERY_1:", -1);
-               break;
-       case 2:
-               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-                       netlogon_dissect_DOMAIN_QUERY_1, NDR_POINTER_UNIQUE,
-                       "DOMAIN_QUERY_1:", -1);
-               break;
-       }
-
+  if( level == 2 ) {
+    /* Specs are not very clear (as usual ...) it seems that the 
+     * structure in both case is a NETLOGON_WORKSTATION_INFO
+     * but in this case only the LSA POLICY INFO will contain
+     * something
+     */
+         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       netlogon_dissect_WORKSTATION_INFORMATION, NDR_POINTER_UNIQUE,
+                         "LSA POLICY INFO", -1);
+  }
+  else {
+    if ( level == 1) {
+         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       netlogon_dissect_WORKSTATION_INFORMATION, NDR_POINTER_UNIQUE,
+                         "WORKSTATION INFORMATION", -1);}
+  }
        return offset;
 }
 
@@ -5832,14 +6506,123 @@ netlogon_dissect_netrlogoncomputeclientdigest_reply(tvbuff_t *tvb, int offset,
 
        return offset;
 }
-
+static int netlogon_dissect_neg_options(tvbuff_t *tvb,proto_tree *tree,guint32 flags,int offset)
+{
+  if (tree) {
+    proto_tree *negotiate_flags_tree = NULL;
+    proto_item *tf = NULL;
+    tf = proto_tree_add_uint (tree,
+            hf_netlogon_neg_flags,
+            tvb, offset, 4,flags);
+    negotiate_flags_tree = proto_item_add_subtree (tf,ett_authenticate_flags);
+
+    /*proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_80000000,
+        tvb, offset, 4, flags);*/
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_40000000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_20000000,
+        tvb, offset, 4, flags);
+    /*
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_10000000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_8000000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_4000000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_2000000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_1000000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_800000,
+        tvb, offset, 4, flags);*/
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_400000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_200000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_100000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_80000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_40000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_20000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_10000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_8000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_4000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_2000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_1000,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_800,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_400,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_200,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_100,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_80,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_40,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_20,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_10,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_8,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_4,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_2,
+        tvb, offset, 4, flags);
+    proto_tree_add_boolean (negotiate_flags_tree,
+        hf_netlogon_neg_flags_1,
+        tvb, offset, 4, flags);
+  }
+  return 0;
+}
 static int
 netlogon_dissect_netrserverauthenticate3_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, guint8 *drep)
 {
+  guint32 flags;
        offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
                pinfo, tree, drep);
-
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
                NDR_POINTER_REF, "Acct Name", hf_netlogon_acct_name, 0);
 
@@ -5849,35 +6632,146 @@ netlogon_dissect_netrserverauthenticate3_rqst(tvbuff_t *tvb, int offset,
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
                NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
 
+       offset = dissect_dcerpc_uint64(tvb, offset, pinfo, tree, drep,
+               hf_client_credential, NULL);
+  /*
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
-               "CREDENTIAL: authenticator", -1);
+               "Client Challenge", -1);*/
 
-       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_neg_flags, NULL);
+       /*offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_neg_flags, NULL);*/
+  ALIGN_TO_4_BYTES;
 
+  flags = tvb_get_letohl (tvb, offset);
+  netlogon_dissect_neg_options(tvb,tree,flags,offset);
+  offset +=4;
        return offset;
 }
 
+static guint32 get_keytab_as_list(md4_pass **p_pass_list)
+{
+  enc_key_t *ek;
+  md4_pass* pass_list;
+  int i = 0;
+  guint32 nb_pass = 0;
+
+  for(ek=enc_key_list;ek;ek=ek->next){
+    if( ek->keylength == 16 ) {
+      nb_pass++;
+    }
+  }
+  *p_pass_list = ep_alloc(nb_pass*sizeof(md4_pass));
+  pass_list=*p_pass_list;
+
+  for(ek=enc_key_list;ek;ek=ek->next){
+  /*    fprintf(stderr,"Type %x, len %d, orig: %s\n",ek->keytype,ek->keylength,ek->key_origin);*/
+
+    if( ek->keylength == 16 ) {
+      memcpy(pass_list[i].md4,ek->keyvalue,16);
+      i++;
+    }
+  }
+  return nb_pass;
+
+}
 
 static int
 netlogon_dissect_netrserverauthenticate3_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, guint8 *drep)
 {
-       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+  guint32 flags;
+  netlogon_auth_vars *vars;
+  netlogon_auth_key key;
+  guint64 server_cred;
+
+       offset = dissect_dcerpc_uint64(tvb, offset, pinfo, tree, drep,
+               hf_server_credential, &server_cred);
+       /*
+  offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
                "CREDENTIAL pointer: unknown_NETLOGON_CREDENTIAL", -1);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_neg_flags, NULL);
+               hf_netlogon_neg_flags, NULL);*/
+  flags = tvb_get_letohl (tvb, offset);
+  netlogon_dissect_neg_options(tvb,tree,flags,offset);
+  offset +=4;
 
-       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+  ALIGN_TO_4_BYTES;
+       offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+               hf_server_rid, NULL);
+/*     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_pointer_long, NDR_POINTER_REF,
-               "ULONG: unknown_ULONG", hf_netlogon_unknown_long);
+               "ULONG: unknown_ULONG", hf_netlogon_unknown_long);*/
 
        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
                                  hf_netlogon_rc, NULL);
 
+  generate_hash_key(pinfo,1,&key);
+
+  vars = g_hash_table_lookup(netlogon_auths, &key);
+  if(vars != NULL) {
+    md4_pass *pass_list;
+    guint32 list_size = 0;
+    guint8 session_key[16];
+    md4_pass password;
+    int found = 0;
+    unsigned int i = 0;
+
+    vars->flags = flags;
+    vars->can_decrypt = FALSE;
+    list_size = get_keytab_as_list(&pass_list);
+    if( flags & NETLOGON_FLAG_STRONGKEY ) {
+      guint8 zeros[4];
+      guint8 md5[16];
+      md5_state_t md5state;
+      guint8 buf[8];
+      guint64 calculated_cred;
+
+
+      memset(zeros,0,4);
+      md5_init(&md5state);
+      md5_append(&md5state,zeros,4);
+      md5_append(&md5state,(unsigned char*)&vars->client_challenge,8);
+      md5_append(&md5state,(unsigned char*)&vars->server_challenge,8);
+      md5_finish(&md5state,md5);
+      /*printnbyte(md5,8,"MD5:","\n");*/
+      printnbyte((guint8*)&server_cred,8,"Server creds:","\n");
+      for(i=0;i<list_size;i++)
+      {
+        password = pass_list[i];
+        md5_hmac(md5,16,(guint8*) &password,16,session_key);
+        crypt_des_ecb(buf,(unsigned char*)&vars->server_challenge,session_key,1);
+        crypt_des_ecb((unsigned char*)&calculated_cred,buf,session_key+7,1);
+        printnbyte((guint8*)&calculated_cred,8,"Calculated creds:","\n");
+        if(calculated_cred==server_cred) {
+          found = 1;
+          break;
+        }
+      }
+    }
+    else if( flags&NETLOGON_FLAG_USEAES)
+    {
+      /*Not implemented*/
+      memset(session_key,0,16);
+    }
+    else
+    {
+      /*Not implemented*/
+      memset(session_key,0,16);
+    }
+    if(found) {
+      memcpy(&vars->session_key,session_key,16);
+      fprintf(stderr,"Found the good session key !\n");
+    }
+    else {
+      memset(&vars->session_key,0,16);
+    }
+     
+
+
+  }
        return offset;
 }
 
@@ -5953,28 +6847,22 @@ netlogon_dissect_netrlogongetdomaininfo_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, guint8 *drep)
 {
        /* Unlike the other NETLOGON RPCs, this is not a unique pointer. */
-       offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
-               NDR_POINTER_REF, "Server Handle", hf_netlogon_computer_name, 0);
-
+  offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+             NDR_POINTER_REF, "Server Handle", hf_netlogon_computer_name, 0);
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
                NDR_POINTER_UNIQUE, "Computer Name", 
                hf_netlogon_computer_name, 0);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
-               "AUTHENTICATOR: credential", -1);
-
-       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
-               hf_netlogon_unknown_long, NULL);
+               "AUTHENTICATOR: client", -1);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
                "AUTHENTICATOR: return_authenticator", -1);
-
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-               netlogon_dissect_DOMAIN_QUERY, NDR_POINTER_REF,
-               "DOMAIN_QUERY: ", -1);
-
+               netlogon_dissect_WORKSTATION_BUFFER, NDR_POINTER_REF,
+               "WORKSTATION_BUFFER", -1);
        return offset;
 }
 
@@ -5988,8 +6876,8 @@ netlogon_dissect_netrlogongetdomaininfo_reply(tvbuff_t *tvb, int offset,
                "AUTHENTICATOR: return_authenticator", -1);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-               netlogon_dissect_DOMAIN_INFO, NDR_POINTER_REF,
-               "DOMAIN_INFO", -1);
+               netlogon_dissect_DOMAIN_INFORMATION, NDR_POINTER_REF,
+               "DOMAIN_INFORMATION", -1);
 
        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
                                  hf_netlogon_rc, NULL);
@@ -6355,7 +7243,26 @@ static int
 netlogon_dissect_netrlogonsamlogonex_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, guint8 *drep)
 {
+
+       offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+               NDR_POINTER_UNIQUE, "LogonServer", 
+               hf_netlogon_computer_name, 0);
        offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+               NDR_POINTER_UNIQUE, "Computer Name", 
+               hf_netlogon_computer_name, 0);
+       offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_level16, NULL);
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_LEVEL, NDR_POINTER_REF,
+               "LEVEL: LogonLevel", -1);
+
+       offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_validation_level, NULL);
+       
+  offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, drep);
+
+/*
+  offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
                NDR_POINTER_UNIQUE, "unknown string", 
                hf_netlogon_unknown_string, 0);
 
@@ -6375,7 +7282,7 @@ netlogon_dissect_netrlogonsamlogonex_rqst(tvbuff_t *tvb, int offset,
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
-               "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
+               "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);*/
        return offset;
 }
 
@@ -6384,6 +7291,18 @@ static int
 netlogon_dissect_netrlogonsamlogonex_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, guint8 *drep)
 {
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               netlogon_dissect_VALIDATION, NDR_POINTER_REF,
+               "VALIDATION:", -1);
+
+       offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
+               hf_netlogon_authoritative, NULL);
+  
+  offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, drep);
+
+       offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+                                 hf_netlogon_rc, NULL);
+/*
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                netlogon_dissect_VALIDATION, NDR_POINTER_UNIQUE,
                "VALIDATION: unknown_NETLOGON_VALIDATION", -1);
@@ -6398,7 +7317,7 @@ netlogon_dissect_netrlogonsamlogonex_reply(tvbuff_t *tvb, int offset,
 
        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
                                  hf_netlogon_rc, NULL);
-
+*/
        return offset;
 }
 
@@ -6696,54 +7615,194 @@ static dcerpc_sub_dissector dcerpc_netlogon_dissectors[] = {
        { NETLOGON_NETRGETFORESTTRUSTINFORMATION, "NetrGetForestTrustInformation",
                NULL, NULL },
        { NETLOGON_NETRLOGONSAMLOGONWITHFLAGS, "NetrLogonSamLogonWithFlags", 
-               NULL, NULL },
+               netlogon_dissect_netrlogonsamlogonflags_rqst,
+               netlogon_dissect_netrlogonsamlogonflags_reply },
        { NETLOGON_NETRSERVERGETTRUSTINFO, "NetrServerGetTrustInfo",
                NULL, NULL },
         {0, NULL, NULL,  NULL }
 };
 
 static int hf_netlogon_secchan_verf = -1;
-static int hf_netlogon_secchan_verf_sig = -1;
+static int hf_netlogon_secchan_verf_sigalg = -1;
+static int hf_netlogon_secchan_verf_sealalg = -1;
+static int hf_netlogon_secchan_verf_pad = -1;
+static int hf_netlogon_secchan_verf_flag = -1;
 static int hf_netlogon_secchan_verf_digest = -1;
 static int hf_netlogon_secchan_verf_seq = -1;
 static int hf_netlogon_secchan_verf_nonce = -1;
 
+static int get_seal_key(const guint8 *session_key,int key_len,guint64 sequence,guint8* seal_key)
+{
+  guint8 zeros[4];
+  guint8 *buf = g_malloc(key_len);
+  guint8 buf2[16];
+  guint8 zero_sk[16];
+  int i = 0;
+  memset(zero_sk,0,16);
+  memset(seal_key,0,16);
+  if(memcmp(session_key,zero_sk,16)) {
+    memset(zeros,0,4);
+    for(i=0;i<key_len;i++) {
+      buf[i] = session_key[i] ^ 0xF0;
+    } 
+    md5_hmac(zeros,4,buf,key_len,buf2);
+    md5_hmac((guint8*)&sequence,8,buf2,16,seal_key);
+    g_free(buf);
+    return 1;
+  }
+  else {
+    g_free(buf);
+    return 0;
+  }
+  
+}
+
+static guint64 uncrypt_sequence(guint8* session_key,guint64 checksum,guint64 enc_seq,unsigned char is_server _U_)
+{
+  guint8 zeros[4];
+  guint8 buf[16];
+  guint8 key[16];
+  rc4_state_struct rc4state;
+  guint8 *p_seq = (guint8*) &enc_seq;
+  /*guint32 temp;*/
+
+  memset(zeros,0,4);
+  md5_hmac(zeros,4,session_key,16,buf);
+  md5_hmac((guint8*)&checksum,8,buf,16,key);
+  
+  crypt_rc4_init(&rc4state,key,16);
+  crypt_rc4(&rc4state,p_seq,8);
+  /*temp = *((guint32*)p_seq);
+  *((guint32*)p_seq) = *((guint32*)p_seq+1);
+  *((guint32*)p_seq+1) = temp;
+  
+  if(!is_server) {
+    *p_seq = *p_seq & 0x7F;
+  }
+  */
+  return enc_seq;
+}
+
+static tvbuff_t *
+dissect_packet_data(tvbuff_t *tvb ,tvbuff_t *auth_tvb _U_,
+     int offset , packet_info *pinfo ,dcerpc_auth_info *auth_info _U_,unsigned char is_server)
+{
+
+  tvbuff_t  *buf = NULL;
+  guint8* decrypted;
+  netlogon_auth_vars *vars;
+  netlogon_auth_key key;
+  /*fprintf(stderr,"Dissection of request data offset %d len=%d on packet %d\n",offset,tvb_length_remaining(tvb,offset),pinfo->fd->num);*/
+
+  generate_hash_key(pinfo,is_server,&key);
+  vars = g_hash_table_lookup(netlogon_auths, &key);
+
+  if(vars != NULL  && vars->can_decrypt == TRUE) {
+   rc4_state_struct rc4state;
+   int data_len = tvb_length_remaining(tvb,offset);
+   guint64 copyconfounder = vars->confounder;
+
+   crypt_rc4_init(&rc4state,vars->encryption_key,16);
+   crypt_rc4(&rc4state,(guint8*)&copyconfounder,8);
+   decrypted = tvb_memdup(tvb, offset,data_len);
+   crypt_rc4_init(&rc4state,vars->encryption_key,16);
+   crypt_rc4(&rc4state,decrypted,data_len);
+   buf = tvb_new_real_data(decrypted, data_len, data_len);
+
+   /*printnbyte((guint8*)&copyconfounder,8,"Decrypted confounder","\n");
+   printnbyte(decrypted,data_len,"Data: ","\n");*/
+  }
+  else {
+    fprintf(stderr,"Vars not found %d\n",g_hash_table_size(netlogon_auths));
+    return(buf);
+  }
+
+  return(buf);
+}
+
+static tvbuff_t* dissect_request_data( tvbuff_t *tvb ,tvbuff_t *auth_tvb ,
+       int offset , packet_info *pinfo ,dcerpc_auth_info *auth_info )
+{
+  return dissect_packet_data(tvb,auth_tvb,offset,pinfo,auth_info,0);
+}
+static tvbuff_t* dissect_response_data( tvbuff_t *tvb ,tvbuff_t *auth_tvb ,
+       int offset , packet_info *pinfo ,dcerpc_auth_info *auth_info )
+{
+  return dissect_packet_data(tvb,auth_tvb,offset,pinfo,auth_info,1);
+}
+  
 static int
 dissect_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, 
-                    proto_tree *tree, guint8 *drep _U_)
-{
-          proto_item *vf = NULL;
-          proto_tree *subtree = NULL;
-         
-          /*
-           * Create a new tree, and split into 4 components ...
-           */
-          vf = proto_tree_add_item(tree, hf_netlogon_secchan_verf, tvb,
-              offset, -1, FALSE);
-          subtree = proto_item_add_subtree(vf, ett_secchan_verf);
-
-          proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sig, tvb,
-              offset, 8, FALSE);
-         offset += 8;
-
-          proto_tree_add_item(subtree, hf_netlogon_secchan_verf_digest, tvb,
-              offset, 8, FALSE);
-         offset += 8;
-
-          proto_tree_add_item(subtree, hf_netlogon_secchan_verf_seq, tvb,
-              offset, 8, FALSE);
-         offset += 8;
-
-         /* In some cases the nonce isn't present although it isn't clear
-            why this is so. */
-
-         if (tvb_bytes_exist(tvb, offset, 8)) {
-                 proto_tree_add_item(subtree, hf_netlogon_secchan_verf_nonce,
-                                     tvb, offset, 8, FALSE);
-                 offset += 8;
-         }
-
-         return offset;
+                    proto_tree *tree, guint8 *drep _U_, unsigned char is_server)
+{
+  netlogon_auth_vars *vars;
+  netlogon_auth_key key;
+  proto_item *vf = NULL;
+  proto_tree *subtree = NULL;
+  guint64 encrypted_seq;
+  guint64 digest;
+  guint64 confounder;
+
+  if(  ! seen.isseen || seen.num != pinfo->fd->num ) {
+    generate_hash_key(pinfo,is_server,&key);
+    vars = g_hash_table_lookup(netlogon_auths,(gconstpointer*) &key);
+    /*
+     * Create a new tree, and split into x components ...
+     */
+    vf = proto_tree_add_item(tree, hf_netlogon_secchan_verf, tvb,
+                             offset, -1, FALSE);
+    subtree = proto_item_add_subtree(vf, ett_secchan_verf);
+
+    proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sigalg, tvb,
+                        offset, 2, TRUE);
+    proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sealalg, tvb,
+                        offset+2, 2, TRUE);
+    proto_tree_add_item(subtree, hf_netlogon_secchan_verf_pad, tvb,
+                        offset+4, 2, FALSE);
+    proto_tree_add_item(subtree, hf_netlogon_secchan_verf_flag, tvb,
+                        offset+6, 2, FALSE);
+    offset += 8;
+
+    offset = dissect_dcerpc_uint64(tvb, offset, pinfo, subtree, drep,
+              hf_netlogon_secchan_verf_seq, &encrypted_seq);
+
+    offset = dissect_dcerpc_uint64(tvb, offset, pinfo, subtree, drep,
+              hf_netlogon_secchan_verf_digest, &digest);
+
+    /* In some cases the nonce if the data/signture are encrypted ("integrity/seal  in MS language")*/
+
+    if (tvb_bytes_exist(tvb, offset, 8)) {
+        offset = dissect_dcerpc_uint64(tvb, offset, pinfo, subtree, drep,
+                   hf_netlogon_secchan_verf_nonce, &confounder);
+    }
+    if( vars ) {
+      vars->confounder = confounder;
+      vars->seq = uncrypt_sequence(vars->session_key,digest,encrypted_seq,is_server);
+      if(get_seal_key(vars->session_key,16,vars->seq,vars->encryption_key))
+      {
+        vars->can_decrypt = TRUE;
+      }
+    }
+    else
+    {
+      fprintf(stderr,"Vars not found %d\n",g_hash_table_size(netlogon_auths));
+    }
+    seen.isseen = TRUE;
+    seen.num = pinfo->fd->num;
+  }
+       return offset;
+}
+static int
+dissect_request_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo , 
+                    proto_tree *tree, guint8 *drep )
+{
+  return dissect_secchan_verf(tvb,offset,pinfo,tree,drep,0);
+}
+static int
+dissect_response_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo , 
+                    proto_tree *tree, guint8 *drep )
+{
+  return dissect_secchan_verf(tvb,offset,pinfo,tree,drep,1);
 }
 
 /* Secure channel types */
@@ -6754,7 +7813,14 @@ static const value_string sec_chan_type_vals[] = {
        { SEC_CHAN_BDC,    "Backup domain controller" },
        { 0, NULL }
 };
-
+static void 
+netlogon_reassemble_init(void)
+{
+  if (netlogon_auths){
+    g_hash_table_destroy (netlogon_auths);
+  }
+  netlogon_auths = g_hash_table_new (netlogon_auth_hash, netlogon_auth_equal);
+ }
 void
 proto_register_dcerpc_netlogon(void)
 {
@@ -6860,12 +7926,131 @@ static hf_register_info hf[] = {
                "Attributes", "netlogon.attrs", FT_UINT32, BASE_HEX,
                NULL, 0, NULL, HFILL }},
 
+       { &hf_netlogon_lsapolicy_referentid,
+               { "Referent ID", "netlogon.lsapolicy.referentID", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Referent ID", HFILL }},
+
+       { &hf_netlogon_lsapolicy_len,
+               { "Length", "netlogon.lsapolicy.length", FT_UINT32, BASE_DEC,
+               NULL, 0x0, "Length of the policy buffer", HFILL }},
+
+       { &hf_netlogon_lsapolicy_pointer,
+               { "Pointer", "netlogon.lsapolicy.length", FT_BYTES, BASE_HEX,
+               NULL, 0x0, "Pointer to LSA POLICY", HFILL }},
+
        { &hf_netlogon_unknown_string,
                { "Unknown string", "netlogon.unknown_string", FT_STRING, BASE_NONE,
                NULL, 0, "Unknown string. If you know what this is, contact wireshark developers.", HFILL }},
+
+       { &hf_netlogon_dummy_string,
+               { "Dummy String", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_trust_extention,
+               { "Trust extension", "netlogon.trust.extention", FT_STRING, BASE_NONE,
+               NULL, 0, "Trusts extension.", HFILL }},
+
+       { &hf_netlogon_trust_offset,
+               { "Offset", "netlogon.trust.extention_offset", FT_UINT32, BASE_DEC,
+               NULL, 0, "Trusts extension.", HFILL }},
+
+       { &hf_netlogon_trust_len,
+               { "Length", "netlogon.trust.extention_length", FT_UINT32, BASE_DEC,
+               NULL, 0, "Length", HFILL }},
+
+       { &hf_netlogon_trust_max,
+               { "Max Count", "netlogon.trust.extention.maxcount", FT_UINT32, BASE_DEC,
+               NULL, 0, "Max Count", HFILL }},
+
+       { &hf_netlogon_dummy_string2,
+               { "Dummy String2", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 2. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy_string3,
+               { "Dummy String3", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 3. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy_string4,
+               { "Dummy String4", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 4. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy_string5,
+               { "Dummy String5", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 5. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy_string6,
+               { "Dummy String6", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 6. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy_string7,
+               { "Dummy String7", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 7. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy_string8,
+               { "Dummy String8", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 8. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy_string9,
+               { "Dummy String9", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 9. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy_string10,
+               { "Dummy String10", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+               NULL, 0, "Dummy String 10. Used is reserved for next evolutions.", HFILL }},
+
        { &hf_netlogon_unknown_long,
                { "Unknown long", "netlogon.unknown.long", FT_UINT32, BASE_HEX,
                NULL, 0x0, "Unknown long. If you know what this is, contact wireshark developers.", HFILL }},
+
+       { &hf_netlogon_dummy1_long,
+               { "Dummy1 Long", "netlogon.dummy.long1", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 1. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy2_long,
+               { "Dummy2 Long", "netlogon.dummy.long2", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 2. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy3_long,
+               { "Dummy3 Long", "netlogon.dummy.long3", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 3. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy4_long,
+               { "Dummy4 Long", "netlogon.dummy.long4", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 4. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy5_long,
+               { "Dummy5 Long", "netlogon.dummy.long5", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 5. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy6_long,
+               { "Dummy6 Long", "netlogon.dummy.long6", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 6. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy7_long,
+               { "Dummy7 Long", "netlogon.dummy.long7", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 7. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy8_long,
+               { "Dummy8 Long", "netlogon.dummy.long8", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 8. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy9_long,
+               { "Dummy9 Long", "netlogon.dummy.long9", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 9. Used is reserved for next evolutions.", HFILL }},
+
+       { &hf_netlogon_dummy10_long,
+               { "Dummy10 Long", "netlogon.dummy.long10", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Dummy long 10. Used is reserved for next evolutions.", HFILL }},
+
+  
+       { &hf_netlogon_supportedenctypes,
+               { "Supported Encryption Types", "netlogon.encryption.types", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Encryption types", HFILL }},
+
+       { &hf_netlogon_workstation_flags,
+               { "Workstation Flags", "netlogon.workstation.flags", FT_UINT32, BASE_HEX,
+               NULL, 0x0, "Flags", HFILL }},
+
        { &hf_netlogon_reserved,
                { "Reserved", "netlogon.reserved", FT_UINT32, BASE_HEX,
                NULL, 0x0, NULL, HFILL }},
@@ -7049,6 +8234,10 @@ static hf_register_info hf[] = {
                { "Wkst Name", "netlogon.wkst.name", FT_STRING, BASE_NONE,
                NULL, 0, "Workstation Name", HFILL }},
 
+       { &hf_netlogon_os_version,
+               { "OS version", "netlogon.os.version", FT_STRING, BASE_NONE,
+               NULL, 0, "OS Version", HFILL }},
+
        { &hf_netlogon_workstation_os,
                { "Wkst OS", "netlogon.wkst.os", FT_STRING, BASE_NONE,
                NULL, 0, "Workstation OS", HFILL }},
@@ -7081,6 +8270,10 @@ static hf_register_info hf[] = {
                { "DNS Domain", "netlogon.dns_domain", FT_STRING, BASE_NONE,
                NULL, 0, "DNS Domain Name", HFILL }},
 
+       { &hf_netlogon_ad_client_dns_name,
+               { "Client DNS Name", "netlogon.client_dns_name", FT_STRING, BASE_NONE,
+               NULL, 0, "Client DNS Name", HFILL }},
+
        { &hf_netlogon_domain_name,
                { "Domain", "netlogon.domain", FT_STRING, BASE_NONE,
                NULL, 0, "Domain Name", HFILL }},
@@ -7093,6 +8286,14 @@ static hf_register_info hf[] = {
                { "Trusted DC", "netlogon.trusted_dc", FT_STRING, BASE_NONE,
                NULL, 0, NULL, HFILL }},
 
+       { &hf_netlogon_logon_dnslogondomainname,
+               { "DNS Logon Domain name", "netlogon.logon.dnslogondomainname", FT_STRING, BASE_NONE,
+               NULL, 0, "DNS Name of the logon domain", HFILL }},
+
+       { &hf_netlogon_logon_upn,
+               { "UPN", "netlogon.logon.upn", FT_STRING, BASE_NONE,
+               NULL, 0, "User Principal Name", HFILL }},
+
        { &hf_netlogon_logonsrv_handle,
                { "Handle", "netlogon.handle", FT_STRING, BASE_NONE,
                NULL, 0, "Logon Srv Handle", HFILL }},
@@ -7194,14 +8395,14 @@ static hf_register_info hf[] = {
                NULL, 0x0, "Number of RIDs", HFILL }},
 
        { &hf_netlogon_num_controllers,
-               { "Num DCs", "netlogon.num_dc", FT_UINT32, BASE_DEC,
-               NULL, 0x0, "Number of domain controllers", HFILL }},
+    { "Num DCs", "netlogon.num_dc", FT_UINT32, BASE_DEC,
+    NULL, 0x0, "Number of domain controllers", HFILL }},
 
-       { &hf_netlogon_num_other_groups,
-               { "Num Other Groups", "netlogon.num_other_groups", FT_UINT32, BASE_DEC,
-               NULL, 0x0, NULL, HFILL }},
+  { &hf_netlogon_num_sid,
+    { "Num Extra SID", "netlogon.num_sid", FT_UINT32, BASE_DEC,
+    NULL, 0x0, "", HFILL }},
 
-       { &hf_netlogon_flags,
+  { &hf_netlogon_flags,
                { "Flags", "netlogon.flags", FT_UINT32, BASE_HEX,
                NULL, 0x0, NULL, HFILL }},
 
@@ -7282,9 +8483,105 @@ static hf_register_info hf[] = {
                NULL, 0x0, NULL, HFILL }},
 
        { &hf_netlogon_neg_flags,
-               { "Neg Flags", "netlogon.neg_flags", FT_UINT32, BASE_HEX,
+               { "Negotiation options", "netlogon.neg_flags", FT_UINT32, BASE_HEX,
                NULL, 0x0, "Negotiation Flags", HFILL }},
 
+       { &hf_netlogon_neg_flags_80000000,
+    { "Not used 80000000", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80000000, "Not used", HFILL }},
+
+       { &hf_netlogon_neg_flags_40000000,
+    { "Authenticated RPC supported", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40000000, "Authenticated RPC supported", HFILL }},
+
+       { &hf_netlogon_neg_flags_20000000,
+    { "Authenticated RPC via lsass supported", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20000000, "rpc via lsass", HFILL }},
+
+       { &hf_netlogon_neg_flags_10000000,
+    { "Not used 10000000", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10000000, "Not used", HFILL }},
+
+       { &hf_netlogon_neg_flags_8000000,
+    { "Not used 8000000", "ntlmssp.neg_flags.na800000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8000000, "Not used", HFILL }},
+
+       { &hf_netlogon_neg_flags_4000000,
+    { "Not used 4000000", "ntlmssp.neg_flags.na400000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_4000000, "Not used", HFILL }},
+
+       { &hf_netlogon_neg_flags_2000000,
+    { "Not used 2000000", "ntlmssp.neg_flags.na200000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2000000, "Not used", HFILL }},
+
+       { &hf_netlogon_neg_flags_1000000,
+    { "Not used 1000000", "ntlmssp.neg_flags.na100000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_1000000, "Not used", HFILL }},
+
+       { &hf_netlogon_neg_flags_800000,
+    { "Not used 800000", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_800000, "Not used", HFILL }},
+
+       { &hf_netlogon_neg_flags_400000,
+    { "AES & SHA2 supported", "ntlmssp.neg_flags.na400000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_USEAES, "AES&SHA2", HFILL }},
+
+       { &hf_netlogon_neg_flags_200000,
+    { "RODC pass-through", "ntlmssp.neg_flags.na200000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_200000, "rodc pt", HFILL }},
+
+       { &hf_netlogon_neg_flags_100000,
+    { "NO NT4 emulation", "ntlmssp.neg_flags.na100000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_100000, "No NT4 emu", HFILL }},
+
+       { &hf_netlogon_neg_flags_80000,
+    { "Cross forest trust", "ntlmssp.neg_flags.na80000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80000, "Cross forest trust", HFILL }},
+
+       { &hf_netlogon_neg_flags_40000,
+    { "GetDomainInfo supported", "ntlmssp.neg_flags.na40000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40000, "GetDomainInfo", HFILL }},
+
+       { &hf_netlogon_neg_flags_20000,
+    { "ServerPasswordSet2 supported", "ntlmssp.neg_flags.na20000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20000, "PasswordSet2", HFILL }},
+
+       { &hf_netlogon_neg_flags_10000,
+    { "DNS trusts supported", "ntlmssp.neg_flags.na10000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10000, "DNS Trusts", HFILL }},
+
+       { &hf_netlogon_neg_flags_8000,
+    { "Transitive trusts", "ntlmssp.neg_flags.na8000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8000, "Transitive trust", HFILL }},
+
+       { &hf_netlogon_neg_flags_4000,
+    { "Strong key", "ntlmssp.neg_flags.na4000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_STRONGKEY, "Strong key", HFILL }},
+
+       { &hf_netlogon_neg_flags_2000,
+    { "Avoid replication Auth database", "ntlmssp.neg_flags.na2000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2000, "Avoid replication auth database", HFILL }},
+
+       { &hf_netlogon_neg_flags_1000,
+    { "Avoid replication account database", "ntlmssp.neg_flags.na1000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_1000, "Avoid replication account database", HFILL }},
+
+       { &hf_netlogon_neg_flags_800,
+    { "Concurent RPC", "ntlmssp.neg_flags.na800", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_800, "Concurent RPC", HFILL }},
+
+       { &hf_netlogon_neg_flags_400,
+    { "Generic pass-through", "ntlmssp.neg_flags.na400", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_400, "Generic pass-through", HFILL }},
+
+       { &hf_netlogon_neg_flags_200,
+    { "SendToSam", "ntlmssp.neg_flags.na200", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_200, "SendToSam", HFILL }},
+
+       { &hf_netlogon_neg_flags_100,
+    { "Refusal of password change", "ntlmssp.neg_flags.na100", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_100, "PWD change refusal", HFILL }},
+
+       { &hf_netlogon_neg_flags_80,
+    { "DatabaseRedo call", "ntlmssp.neg_flags.na80", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80, "DatabaseRedo call", HFILL }},
+
+       { &hf_netlogon_neg_flags_40,
+    { "Handle multiple SIDs", "ntlmssp.neg_flags.na40", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40, "Handle multiple SIDs", HFILL }},
+
+       { &hf_netlogon_neg_flags_20,
+    { "Restarting full DC sync", "ntlmssp.neg_flags.na20", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20, "Restarting full DC sync", HFILL }},
+
+       { &hf_netlogon_neg_flags_10,
+    { "BDC handling Changelogs", "ntlmssp.neg_flags.na10", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10, "BDC Changelog", HFILL }},
+
+       { &hf_netlogon_neg_flags_8,
+    { "Promotion count(deprecated)", "ntlmssp.neg_flags.na8", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8, "Promotion count", HFILL }},
+
+       { &hf_netlogon_neg_flags_4,
+    { "RC4 encryption", "ntlmssp.neg_flags.na4", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_4, "RC4", HFILL }},
+
+       { &hf_netlogon_neg_flags_2,
+    { "NT3.5 BDC continious update", "ntlmssp.neg_flags.na2", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2, "NT3.5", HFILL }},
+
+       { &hf_netlogon_neg_flags_1,
+    { "Account lockout", "ntlmssp.neg_flags.na1", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_1, "Account lockout", HFILL }},
+
        { &hf_netlogon_dc_flags,
                { "Domain Controller Flags", "netlogon.dc.flags", FT_UINT32, BASE_HEX,
                NULL, 0x0, NULL, HFILL }},
@@ -7479,6 +8776,30 @@ static hf_register_info hf[] = {
                { "Trust Type", "netlogon.trust_type", FT_UINT32, BASE_DEC,
                VALS(trust_type_vals), 0x0, NULL, HFILL }},
 
+       { &hf_netlogon_extraflags,
+               { "Extra Flags", "netlogon.extra_flags", FT_UINT32, BASE_HEX,
+               NULL, 0x0, NULL, HFILL }},
+
+       { &hf_netlogon_extra_flags_root_forest,
+               { "Request passed to DC of root forest", "netlogon.extra.flags.rootdc",
+                 FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_ROOT_FOREST,
+                 NULL, HFILL }},
+
+       { &hf_netlogon_trust_flags_dc_firsthop,
+               { " DC at the end of the first hop of cross forest", "netlogon.extra.flags.dc_firsthop",
+                 FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_DC_XFOREST,
+                 NULL, HFILL }},
+
+       { &hf_netlogon_trust_flags_rodc_to_dc,
+               { "Request from a RODC to a DC from another domain", "netlogon.extra.flags.rodc_to_dc",
+                 FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_RODC_DIF_DOMAIN,
+                 NULL, HFILL }},
+
+       { &hf_netlogon_trust_flags_rodc_ntlm,
+               { "Request is a NTLM auth passed by a RODC", "netlogon.extra.flags.rodc_ntlm",
+                 FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_NTLM_FROM_RODC,
+                 NULL, HFILL }},
+
        { &hf_netlogon_trust_flags,
                { "Trust Flags", "netlogon.trust_flags", FT_UINT32, BASE_HEX,
                NULL, 0x0, NULL, HFILL }},
@@ -7583,6 +8904,26 @@ static hf_register_info hf[] = {
 
        /* Secure channel dissection */
 
+       { &hf_client_credential,
+         { "Client Credential", "netlogon.clientcred", FT_BYTES, BASE_HEX,
+           NULL, 0x0, "", HFILL }},
+
+       { &hf_server_credential,
+         { "Server Credential", "netlogon.servercred", FT_BYTES, BASE_HEX,
+           NULL, 0x0, "", HFILL }},
+
+       { &hf_server_rid,
+         { "Account RID", "netlogon.serverrid", FT_UINT32, BASE_DEC,
+           NULL, 0x0, "", HFILL }},
+
+       { &hf_client_challenge,
+         { "Client Challenge", "netlogon.clientchallenge", FT_BYTES, BASE_HEX,
+           NULL, 0x0, "", HFILL }},
+
+       { &hf_server_challenge,
+         { "Server Challenge", "netlogon.serverchallenge", FT_BYTES, BASE_HEX,
+           NULL, 0x0, "", HFILL }},
+
        { &hf_netlogon_secchan_bind_unknown1,
          { "Unknown1", "netlogon.secchan.bind.unknown1", FT_UINT32, BASE_HEX,
            NULL, 0x0, NULL, HFILL }},
@@ -7599,6 +8940,14 @@ static hf_register_info hf[] = {
          { "Host", "netlogon.secchan.host", FT_STRING, BASE_NONE,
            NULL, 0, NULL, HFILL }},
 
+       { &hf_netlogon_data_length,
+         { "Length of Data", "netlogon.data.length", FT_UINT32, BASE_DEC,
+           NULL, 0, "", HFILL }},
+
+       { &hf_netlogon_package_name,
+         { "SSP Package Name", "netlogon.data.package_name", FT_STRING, BASE_NONE,
+           NULL, 0, "", HFILL }},
+
        { &hf_netlogon_secchan_bind_ack_unknown1,
          { "Unknown1", "netlogon.secchan.bind_ack.unknown1", FT_UINT32, 
            BASE_HEX, NULL, 0x0, NULL, HFILL }},
@@ -7609,26 +8958,39 @@ static hf_register_info hf[] = {
 
        { &hf_netlogon_secchan_bind_ack_unknown3,
          { "Unknown3", "netlogon.secchan.bind_ack.unknown3", FT_UINT32, 
-           BASE_HEX, NULL, 0x0, NULL, HFILL }},
+       
+        BASE_HEX, NULL, 0x0, "", HFILL }},
 
-        { &hf_netlogon_secchan_verf,
-          { "Secure Channel Verifier", "netlogon.secchan.verifier", FT_NONE, BASE_NONE, 
-           NULL, 0x0, "Verifier", HFILL }},
+  { &hf_netlogon_secchan_verf,
+     { "Secure Channel Verifier", "netlogon.secchan.verifier", FT_NONE, BASE_NONE, 
+        NULL, 0x0, "Verifier", HFILL }},
 
-        { &hf_netlogon_secchan_verf_sig,
-          { "Signature", "netlogon.secchan.sig", FT_BYTES, BASE_NONE, NULL, 
-           0x0, NULL, HFILL }}, 
+  { &hf_netlogon_secchan_verf_sigalg,
+     { "Sign algorithm", "netlogon.secchan.sigalg", FT_UINT16, BASE_HEX, NULL, 
+        0x0, "Signature", HFILL }},
 
-        { &hf_netlogon_secchan_verf_digest,
-          { "Packet Digest", "netlogon.secchan.digest", FT_BYTES, BASE_NONE, NULL, 
-          0x0, NULL, HFILL }}, 
+   { &hf_netlogon_secchan_verf_sealalg,
+     { "Sign algorithm", "netlogon.secchan.sigalg", FT_UINT16, BASE_HEX, NULL, 
+       0x0, "Signature", HFILL }}, 
+ { &hf_netlogon_secchan_verf_pad,
+    { "Padding", "netlogon.secchan.sigalg", FT_BYTES, BASE_HEX, NULL, 
+      0x0, "Signature", HFILL }}, 
+ { &hf_netlogon_secchan_verf_flag,
+    { "Flags", "netlogon.secchan.sigalg", FT_BYTES, BASE_HEX, NULL, 
+    0x0, "Signature", HFILL }}, 
+ { &hf_netlogon_secchan_verf_digest,
+    { "Packet Digest", "netlogon.secchan.digest", FT_BYTES, BASE_HEX, NULL, 
+            0x0, "Packet Digest", HFILL }},
 
       { &hf_netlogon_secchan_verf_seq,
-          { "Sequence No", "netlogon.secchan.seq", FT_BYTES, BASE_NONE, NULL, 
-          0x0, NULL, HFILL }}, 
+ { &hf_netlogon_secchan_verf_seq,
+     { "Sequence No", "netlogon.secchan.seq", FT_BYTES, BASE_HEX, NULL, 
+            0x0, "Sequence No", HFILL }},
 
-        { &hf_netlogon_secchan_verf_nonce,
-          { "Nonce", "netlogon.secchan.nonce", FT_BYTES, BASE_NONE, NULL, 
+  { &hf_netlogon_secchan_verf_nonce,
+         { "Nonce", "netlogon.secchan.nonce", FT_BYTES, BASE_NONE, NULL, 
           0x0, NULL, HFILL }}, 
 
        { &hf_netlogon_group_attrs_mandatory,
@@ -7748,7 +9110,8 @@ static hf_register_info hf[] = {
        };
 
         static gint *ett[] = {
-                &ett_dcerpc_netlogon,
+    &ett_dcerpc_netlogon,
+    &ett_authenticate_flags,
                &ett_CYPHER_VALUE,
                &ett_QUOTA_LIMITS,
                &ett_IDENTITY_INFO,
@@ -7767,6 +9130,7 @@ static hf_register_info hf[] = {
                &ett_DS_DOMAIN_TRUSTS,
                &ett_BLOB,
                &ett_DOMAIN_TRUST_INFO,
+    &ett_LSA_POLICY_INFO,
                &ett_trust_flags,
                &ett_trust_attribs,
                &ett_get_dcname_request_flags,
@@ -7776,6 +9140,7 @@ static hf_register_info hf[] = {
                &ett_secchan_verf,
                &ett_group_attrs,
                &ett_user_flags,
+    &ett_nt_counted_longs_as_string,
                &ett_user_account_control
         };
 
@@ -7785,26 +9150,30 @@ static hf_register_info hf[] = {
         proto_register_field_array(proto_dcerpc_netlogon, hf,
                                   array_length(hf));
         proto_register_subtree_array(ett, array_length(ett));
+        register_init_routine(netlogon_reassemble_init);
+
 }
 
 static dcerpc_auth_subdissector_fns secchan_auth_fns = {
        dissect_secchan_bind_creds,             /* Bind */
        dissect_secchan_bind_ack_creds,         /* Bind ACK */
        NULL,                                   /* AUTH3 */
-       dissect_secchan_verf,                   /* Request verifier */
-       dissect_secchan_verf,                   /* Response verifier */
-       NULL,                                   /* Request data */
-       NULL                                    /* Response data */
+       dissect_request_secchan_verf,                   /* Request verifier */
+       dissect_response_secchan_verf,                  /* Response verifier */
+       dissect_request_data,                                   /* Request data */
+       dissect_response_data                                   /* Response data */
 };
 
 void
 proto_reg_handoff_dcerpc_netlogon(void)
 {
-        /* Register protocol as dcerpc */
+         /* Register protocol as dcerpc */
+  seen.isseen = FALSE;
+  seen.num = 0;
+  dcerpc_init_uuid(proto_dcerpc_netlogon, ett_dcerpc_netlogon,
+                   &uuid_dcerpc_netlogon, ver_dcerpc_netlogon,
+                   dcerpc_netlogon_dissectors, hf_netlogon_opnum);
 
-        dcerpc_init_uuid(proto_dcerpc_netlogon, ett_dcerpc_netlogon,
-                         &uuid_dcerpc_netlogon, ver_dcerpc_netlogon,
-                         dcerpc_netlogon_dissectors, hf_netlogon_opnum);
 
        register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
                                          DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN,
index 6397d34156abd7398440f14b07e995868575989d..1c5a44c78ffd48dc0af47c00bfe3db33bb929bbc 100644 (file)
@@ -62,8 +62,8 @@ gint ett_nt_unicode_string = -1; /* FIXME: make static */
 
 /* Dissect a counted string as a callback to dissect_ndr_pointer_cb() */
 
-static int hf_nt_cs_len = -1;
-static int hf_nt_cs_size = -1;
+int hf_nt_cs_len = -1;
+int hf_nt_cs_size = -1;
 
 int
 dissect_ndr_counted_string_cb(tvbuff_t *tvb, int offset,
index 1e63e1dc9eef32ea1761d76b8fc1c39ef3065356..fb7977c8d844ca87fc283a5c349e1f0eb39b6058 100644 (file)
@@ -252,5 +252,8 @@ void cb_str_postprocess(packet_info *pinfo, proto_tree *tree _U_,
 
 void dcerpc_smb_init(int proto_dcerpc);
 
+/* Used into packet-dcerpc-netlogon.c*/
+int hf_nt_cs_len;
+int hf_nt_cs_size;
 
 #endif /* packet-dcerpc-nt.h */
index cddfdf87a535f222fef4e710a7bf019d68f15469..1d1091c9e40de2faec94e7862b18f5424af4fab7 100644 (file)
@@ -32,6 +32,7 @@
 #include "config.h"
 #endif
 
+#include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 
@@ -550,7 +551,6 @@ static dcerpc_auth_subdissector_fns *get_auth_subdissector_fns(
 
        for (i = 0; (data = g_slist_nth_data(dcerpc_auth_subdissector_list, i)); i++) {
                dcerpc_auth_subdissector *asd = (dcerpc_auth_subdissector *)data;
-
                if (asd->auth_level == auth_level &&
                    asd->auth_type == auth_type)
                        return &asd->auth_fns;
@@ -889,6 +889,7 @@ dcerpc_dg_call_hash (gconstpointer k)
             + (key->act_id.Data4[6] << 8) + (key->act_id.Data4[7] << 0));
 }
 
+
 /* to keep track of matched calls/responses
    this one uses the same value struct as calls, but the key is the frame id
    and call id; there can be more than one call in a frame.
@@ -1332,7 +1333,7 @@ dissect_ndr_cvstring(tvbuff_t *tvb, int offset, packet_info *pinfo,
     dcerpc_info *di;
     proto_item *string_item;
     proto_tree *string_tree;
-    guint32 len, buffer_len;
+    guint32 len, buffer_len, max;
     char *s;
     header_field_info *hfinfo;
 
@@ -1354,20 +1355,34 @@ dissect_ndr_cvstring(tvbuff_t *tvb, int offset, packet_info *pinfo,
     /* NDR array header */
 
     offset = dissect_ndr_uint32(tvb, offset, pinfo, string_tree, drep,
-                                hf_dcerpc_array_max_count, NULL);
+                                hf_dcerpc_array_max_count, &max);
 
     offset = dissect_ndr_uint32(tvb, offset, pinfo, string_tree, drep,
                                 hf_dcerpc_array_offset, NULL);
 
     offset = dissect_ndr_uint32(tvb, offset, pinfo, string_tree, drep,
                                 hf_dcerpc_array_actual_count, &len);
-
     buffer_len = size_is * len;
+    /*buffer_len2 = size_is * max;*/
+    hfinfo = proto_registrar_get_nth(hfindex);
 
     /* Adjust offset */
     if (offset % size_is)
         offset += size_is - (offset % size_is);
-
+    /*if( buffer_len2 != buffer_len && hfinfo->type == FT_STRING && tvb_reported_length_remaining(tvb,offset) > (gint)buffer_len2) {
+      / * Max can be bigger that len 
+       * if the packet is comming from windows it normally means that the 
+       * last two bytes are null terminators. In this case we change the length
+       * in order to consume them ...
+       * If it's from samba then it's more unlikely to be terminator so we carefully check if
+       * it's null terminators or not in order to know if we should consume them * /
+
+      buf = ep_alloc(sizeof(guint8)*buffer_len2);
+      tvb_memcpy(tvb,buf,offset,buffer_len2);
+      if( buf[buffer_len2-2] == 0x0 && buf[buffer_len2-1] == 0x0) {
+        buffer_len = buffer_len2;
+      }
+    }*/
     if (size_is == sizeof(guint16)) {
         /* XXX - use drep to determine the byte order? */
         s = tvb_fake_unicode(tvb, offset, buffer_len / 2, TRUE);
@@ -1377,7 +1392,6 @@ dissect_ndr_cvstring(tvbuff_t *tvb, int offset, packet_info *pinfo,
          * its value be the "fake Unicode" string.
          */
         if (tree && buffer_len) {
-            hfinfo = proto_registrar_get_nth(hfindex);
             tvb_ensure_bytes_exist(tvb, offset, buffer_len);
             if (hfinfo->type == FT_STRING) {
                 proto_tree_add_string(string_tree, hfindex, tvb, offset,
@@ -1446,6 +1460,7 @@ dissect_ndr_char_cvstring(tvbuff_t *tvb, int offset, packet_info *pinfo,
    there for the benefit of null-terminated-string languages
    such as C.  Is this ever used for purely counted strings?
    (Not that it matters if it is.) */
+/* This function should be duplicated to handle properly null terminated strings*/
 int
 dissect_ndr_wchar_cvstring(tvbuff_t *tvb, int offset, packet_info *pinfo,
                        proto_tree *tree, guint8 *drep)
@@ -1890,7 +1905,6 @@ dissect_ndr_pointer_cb(tvbuff_t *tvb, gint offset, packet_info *pinfo,
                */
                return offset;
        }
-
        /*TOP LEVEL REFERENCE POINTER*/
        if( pointers_are_top_level
        &&(type==NDR_POINTER_REF) ){
@@ -2026,7 +2040,6 @@ dissect_ndr_pointer_cb(tvbuff_t *tvb, gint offset, packet_info *pinfo,
 
                /* get the referent id */
                offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep, -1, &id);
-
                tvb_ensure_bytes_exist(tvb, offset-4, 4);
                /* we got a NULL pointer */
                if(id==0){
@@ -2113,8 +2126,8 @@ static void
 show_stub_data (tvbuff_t *tvb, gint offset, proto_tree *dcerpc_tree,
                 dcerpc_auth_info *auth_info, gboolean is_encrypted)
 {
-    int length, plain_length, auth_pad_len;
-    guint auth_pad_offset;
+  int length, plain_length, auth_pad_len;
+  guint auth_pad_offset;
 
     /*
      * We don't show stub data unless we have some in the tvbuff;
@@ -2122,49 +2135,48 @@ show_stub_data (tvbuff_t *tvb, gint offset, proto_tree *dcerpc_tree,
      * bytes, the reported number of bytes, not the number of bytes
      * that happen to be in the tvbuff.
      */
-    if (tvb_length_remaining (tvb, offset) > 0) {
-       auth_pad_len = auth_info?auth_info->auth_pad_len:0;
-        length = tvb_reported_length_remaining (tvb, offset);
+  if (tvb_length_remaining (tvb, offset) > 0) {
+       auth_pad_len = auth_info?auth_info->auth_pad_len:0;
+    length = tvb_reported_length_remaining (tvb, offset);
 
        /* if auth_pad_len is larger than length then we ignore auth_pad_len totally */
-       plain_length = length - auth_pad_len;
-       if (plain_length < 1) {
+       plain_length = length - auth_pad_len;
+         if (plain_length < 1) {
            plain_length = length;
            auth_pad_len = 0;
-       }
-       auth_pad_offset = offset + plain_length;
-
-        if (auth_info != NULL &&
-            auth_info->auth_level == DCE_C_AUTHN_LEVEL_PKT_PRIVACY) {
-            if (is_encrypted) {
-               tvb_ensure_bytes_exist(tvb, offset, length);
+         }
+         auth_pad_offset = offset + plain_length;
+    if (auth_info != NULL &&
+        auth_info->auth_level == DCE_C_AUTHN_LEVEL_PKT_PRIVACY) {
+      if (is_encrypted) {
+                   tvb_ensure_bytes_exist(tvb, offset, length);
                 proto_tree_add_text(dcerpc_tree, tvb, offset, length,
-                                    "Encrypted stub data (%d byte%s)",
-                                    length, plurality(length, "", "s"));
+                "Encrypted stub data (%d byte%s)",
+                length, plurality(length, "", "s"));
                /* is the padding is still inside the encrypted blob, don't display it explicit */
-               auth_pad_len = 0;
-            } else {
-               tvb_ensure_bytes_exist(tvb, offset, plain_length);
-                proto_tree_add_text(dcerpc_tree, tvb, offset, plain_length,
-                                    "Decrypted stub data (%d byte%s)",
-                                    plain_length, plurality(plain_length, "", "s"));
-            }
-        } else {
-           tvb_ensure_bytes_exist(tvb, offset, plain_length);
-            proto_tree_add_text (dcerpc_tree, tvb, offset, plain_length,
-                                 "Stub data (%d byte%s)", plain_length,
-                                 plurality(plain_length, "", "s"));
-        }
-        /* If there is auth padding at the end of the stub, display it */
-        if (auth_pad_len != 0) {
-               tvb_ensure_bytes_exist(tvb, auth_pad_offset, auth_pad_len);
-                proto_tree_add_text (dcerpc_tree, tvb, auth_pad_offset,
-                                     auth_pad_len,
-                                     "Auth Padding (%u byte%s)",
-                                     auth_pad_len,
-                                     plurality(auth_pad_len, "", "s"));
-            }
+                   auth_pad_len = 0;
+      } 
+      else {
+                   tvb_ensure_bytes_exist(tvb, offset, plain_length);
+        proto_tree_add_text(dcerpc_tree, tvb, offset, plain_length,
+            "Decrypted stub data (%d byte%s)",
+            plain_length, plurality(plain_length, "", "s"));
+      }
+    } 
+    else {
+          tvb_ensure_bytes_exist(tvb, offset, plain_length);
+     proto_tree_add_text (dcerpc_tree, tvb, offset, plain_length,
+            "Stub data (%d byte%s)", plain_length,
+            plurality(plain_length, "", "s"));
+    }
+    /* If there is auth padding at the end of the stub, display it */
+    if (auth_pad_len != 0) {
+               tvb_ensure_bytes_exist(tvb, auth_pad_offset, auth_pad_len);
+      proto_tree_add_text (dcerpc_tree, tvb, auth_pad_offset,
+                           auth_pad_len, "Auth Padding (%u byte%s)",
+                           auth_pad_len, plurality(auth_pad_len, "", "s"));
     }
+  }
 }
 
 static int
@@ -2680,6 +2692,7 @@ dissect_dcerpc_cn_bind (tvbuff_t *tvb, gint offset, packet_info *pinfo,
         conv = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
                                   pinfo->srcport, pinfo->destport, 0);
         if (conv == NULL) {
+        fprintf(stderr,"Creating a new conv on packet %d\n",pinfo->fd->num);
             conv = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
                                      pinfo->srcport, pinfo->destport, 0);
         }
@@ -2940,25 +2953,24 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
     proto_item *dcerpc_tree_item;
 
     save_fragmented = pinfo->fragmented;
-
     length = tvb_length_remaining(tvb, offset);
     reported_length = tvb_reported_length_remaining(tvb, offset);
     if (reported_length < 0 ||
-       (guint32)reported_length < auth_info->auth_size) {
+           (guint32)reported_length < auth_info->auth_size) {
        /* We don't even have enough bytes for the authentication
           stuff. */
-       return;
+           return;
     }
     reported_length -= auth_info->auth_size;
     if (length > reported_length)
-       length = reported_length;
+           length = reported_length;
     payload_tvb = tvb_new_subset(tvb, offset, length, reported_length);
 
     auth_tvb=NULL;
     /*dont bother if we dont have the entire tvb */
     /*XXX we should really make sure we calculate auth_info->auth_data
-       and use that one instead of this auth_tvb hack
-    */
+          *and use that one instead of this auth_tvb hack
+     */
     if(tvb_length(tvb)==tvb_reported_length(tvb)){
        if(tvb_length_remaining(tvb, offset+length)>8){
            auth_tvb = tvb_new_subset_remaining(tvb, offset+length+8);
@@ -2978,52 +2990,51 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
 
            /* Start out assuming we won't succeed in decrypting. */
            decrypted_tvb = NULL;
+      /* Schannel needs informations into the footer (verifier) in order to setup decryptions keys 
+       * so we call it in order to have a chance to decypher the data 
+       */
+      if (DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN == auth_info->auth_type) {
+        dissect_dcerpc_cn_auth (tvb, offset, pinfo, dcerpc_tree, hdr, TRUE, auth_info);
+      }
 
            if ((auth_fns = get_auth_subdissector_fns(
                         auth_info->auth_level, auth_info->auth_type))) {
                    tvbuff_t *result;
-
-                   result = decode_encrypted_data(
-                           payload_tvb, auth_tvb, pinfo, auth_fns,
-                           hdr->ptype == PDU_REQ, auth_info);
-
+                   result = decode_encrypted_data( payload_tvb, auth_tvb, pinfo, auth_fns,
+                            hdr->ptype == PDU_REQ, auth_info);
                    if (result) {
-                           if (dcerpc_tree)
-                               proto_tree_add_text(
-                                           dcerpc_tree, payload_tvb, 0, -1,
+                           if (dcerpc_tree) {
+                                   proto_tree_add_text(dcerpc_tree, payload_tvb, 0, -1,
                                            "Encrypted stub data (%d byte%s)",
                                            tvb_reported_length(payload_tvb),
-
-                           plurality(tvb_length(payload_tvb), "", "s"));
-
-                           add_new_data_source(
-                                   pinfo, result, "Decrypted stub data");
-
+                               plurality(tvb_length(payload_tvb), "", "s"));
+          }
+                           add_new_data_source(pinfo, result, "Decrypted stub data");
                            /* We succeeded. */
                            decrypted_tvb = result;
                    }
            }
-    } else
+    } 
+    else
            decrypted_tvb = payload_tvb;
 
     /* if this packet is not fragmented, just dissect it and exit */
-    if(PFC_NOT_FRAGMENTED(hdr)){
-       pinfo->fragmented = FALSE;
+    if(PFC_NOT_FRAGMENTED(hdr)) {
+           pinfo->fragmented = FALSE;
 
-       dcerpc_try_handoff(
-               pinfo, tree, dcerpc_tree, payload_tvb, decrypted_tvb,
-               hdr->drep, di, auth_info);
+           dcerpc_try_handoff( pinfo, tree, dcerpc_tree, payload_tvb, 
+          decrypted_tvb, hdr->drep, di, auth_info);
 
-       pinfo->fragmented = save_fragmented;
-       return;
+          pinfo->fragmented = save_fragmented;
+          return;
     }
 
     /* The packet is fragmented. */
     pinfo->fragmented = TRUE;
 
-       /* debug output of essential fragment data. */
-       /* leave it here for future debugging sessions */
-       /*printf("DCE num:%u offset:%u frag_len:%u tvb_len:%u\n",
+         /* debug output of essential fragment data. */
+         /* leave it here for future debugging sessions */
+         /*printf("DCE num:%u offset:%u frag_len:%u tvb_len:%u\n",
                   pinfo->fd->num, offset, hdr->frag_len, tvb_length(decrypted_tvb));*/
 
     /* if we are not doing reassembly and this is the first fragment
@@ -3194,6 +3205,7 @@ dcerpc_add_conv_to_bind_table(decode_dcerpc_bind_values_t *binding)
         0);
 
     if (!conv) {
+        fprintf(stderr,"Creating a new conv on this bind packet \n");
         conv = conversation_new (
             0,
             &binding->addr_a,
@@ -3238,6 +3250,8 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
     guint32 alloc_hint;
     proto_item *pi;
     proto_item *parent_pi;
+    dcerpc_matched_key matched_key, *new_matched_key;
+    dcerpc_call_value *value;
 
     offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
                                     hf_dcerpc_cn_alloc_hint, &alloc_hint);
@@ -3249,6 +3263,16 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
         proto_item_append_text(parent_pi, " Ctx: %u", ctx_id);
     }
 
+    if (check_col (pinfo->cinfo, COL_DCE_CTX)) {
+               if(pinfo->dcectxid == 0) {
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "%u", ctx_id);
+               } else {
+                       /* this is not the first DCE-RPC request/response in this (TCP?-)PDU,
+                        * prepend a delimiter */
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
+               }
+    }
+
     offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
                                     hf_dcerpc_opnum, &opnum);
 
@@ -3275,123 +3299,120 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
      * and we just have a security context?
      */
     dissect_dcerpc_cn_auth (tvb, offset, pinfo, dcerpc_tree, hdr, FALSE, &auth_info);
-
     conv = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
                               pinfo->srcport, pinfo->destport, 0);
-    if (!conv)
-        show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
+    if (!conv) {
+      /*conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
+                      pinfo->srcport, pinfo->destport, 0);*/
+       fprintf(stderr,"No conv showing raw stuf %d \n",pinfo->fd->num);
+       show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
+    }
     else {
-        dcerpc_matched_key matched_key, *new_matched_key;
-        dcerpc_call_value *value;
-
-       /* !!! we can NOT check flags.visited here since this will interact
-          badly with when SMB handles (i.e. calls the subdissector)
-          and desegmented pdu's .
-          Instead we check if this pdu is already in the matched table or not
-       */
-       matched_key.frame = pinfo->fd->num;
-       matched_key.call_id = hdr->call_id;
-       value = g_hash_table_lookup(dcerpc_matched, &matched_key);
-       if(!value){
-               dcerpc_bind_key bind_key;
-               dcerpc_bind_value *bind_value;
-
-               bind_key.conv=conv;
-               bind_key.ctx_id=ctx_id;
-               bind_key.smb_fid=dcerpc_get_transport_salt(pinfo);
-
-               if((bind_value=g_hash_table_lookup(dcerpc_binds, &bind_key)) ){
-                       if(!(hdr->flags&PFC_FIRST_FRAG)){
-                               dcerpc_cn_call_key call_key;
-                               dcerpc_call_value *call_value;
-
-                               call_key.conv=conv;
-                               call_key.call_id=hdr->call_id;
-                               call_key.smb_fid=dcerpc_get_transport_salt(pinfo);
-                               if((call_value=g_hash_table_lookup(dcerpc_cn_calls, &call_key))){
-                                       new_matched_key = se_alloc(sizeof (dcerpc_matched_key));
-                                       *new_matched_key = matched_key;
-                                       g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
-                                       value = call_value;
-                               }
-                       } else {
-                               dcerpc_cn_call_key *call_key;
-                               dcerpc_call_value *call_value;
-
-                               /* We found the binding and it is the first fragment
-                                  (or a complete PDU) of a dcerpc pdu so just add
-                                  the call to both the call table and the
-                                  matched table
-                               */
-                               call_key=se_alloc (sizeof (dcerpc_cn_call_key));
-                               call_key->conv=conv;
-                               call_key->call_id=hdr->call_id;
-                               call_key->smb_fid=dcerpc_get_transport_salt(pinfo);
-
-                               /* if there is already a matching call in the table
-                                  remove it so it is replaced with the new one */
-                               if(g_hash_table_lookup(dcerpc_cn_calls, call_key)){
-                                       g_hash_table_remove(dcerpc_cn_calls, call_key);
-                               }
-
-                               call_value=se_alloc (sizeof (dcerpc_call_value));
-                               call_value->uuid = bind_value->uuid;
-                               call_value->ver = bind_value->ver;
-                call_value->object_uuid = obj_id;
-                               call_value->opnum = opnum;
-                               call_value->req_frame=pinfo->fd->num;
-                               call_value->req_time=pinfo->fd->abs_ts;
-                               call_value->rep_frame=0;
-                               call_value->max_ptr=0;
-                               call_value->se_data = NULL;
-                               call_value->private_data = NULL;
-                               call_value->pol = NULL;
-                               g_hash_table_insert (dcerpc_cn_calls, call_key, call_value);
-
-                               new_matched_key = se_alloc(sizeof (dcerpc_matched_key));
-                               *new_matched_key = matched_key;
-                               g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
-                               value = call_value;
-                       }
-               }
-       }
-
-        if (value) {
-            dcerpc_info *di;
-
-            di=get_next_di();
-            /* handoff this call */
-           di->conv = conv;
-           di->call_id = hdr->call_id;
-           di->smb_fid = dcerpc_get_transport_salt(pinfo);
-           di->ptype = PDU_REQ;
-           di->call_data = value;
-               di->hf_index = -1;
-
-           if(value->rep_frame!=0){
-               pi = proto_tree_add_uint(dcerpc_tree, hf_dcerpc_response_in,
-                                   tvb, 0, 0, value->rep_frame);
+    /* !!! we can NOT check flags.visited here since this will interact
+       badly with when SMB handles (i.e. calls the subdissector)
+       and desegmented pdu's .
+       Instead we check if this pdu is already in the matched table or not
+    */
+      matched_key.frame = pinfo->fd->num;
+      matched_key.call_id = hdr->call_id;
+      value = g_hash_table_lookup(dcerpc_matched, &matched_key);
+      if(!value) {
+        dcerpc_bind_key bind_key;
+        dcerpc_bind_value *bind_value;
+
+        bind_key.conv=conv;
+        bind_key.ctx_id=ctx_id;
+        bind_key.smb_fid=dcerpc_get_transport_salt(pinfo);
+        if((bind_value=g_hash_table_lookup(dcerpc_binds, &bind_key)) ){
+        if(!(hdr->flags&PFC_FIRST_FRAG)){
+          dcerpc_cn_call_key call_key;
+          dcerpc_call_value *call_value;
+
+          call_key.conv=conv;
+          call_key.call_id=hdr->call_id;
+          call_key.smb_fid=dcerpc_get_transport_salt(pinfo);
+          if((call_value=g_hash_table_lookup(dcerpc_cn_calls, &call_key))){
+            new_matched_key = se_alloc(sizeof (dcerpc_matched_key));
+            *new_matched_key = matched_key;
+            g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
+            value = call_value;
+          }
+        } 
+        else {
+          dcerpc_cn_call_key *call_key;
+          dcerpc_call_value *call_value;
+
+          /* We found the binding and it is the first fragment
+             (or a complete PDU) of a dcerpc pdu so just add
+             the call to both the call table and the
+             matched table
+          */
+          call_key=se_alloc (sizeof (dcerpc_cn_call_key));
+          call_key->conv=conv;
+          call_key->call_id=hdr->call_id;
+          call_key->smb_fid=dcerpc_get_transport_salt(pinfo);
+
+          /* if there is already a matching call in the table
+             remove it so it is replaced with the new one */
+          if(g_hash_table_lookup(dcerpc_cn_calls, call_key)){
+            g_hash_table_remove(dcerpc_cn_calls, call_key);
+          }
+
+          call_value=se_alloc (sizeof (dcerpc_call_value));
+          call_value->uuid = bind_value->uuid;
+          call_value->ver = bind_value->ver;
+          call_value->object_uuid = obj_id;
+          call_value->opnum = opnum;
+          call_value->req_frame=pinfo->fd->num;
+          call_value->req_time=pinfo->fd->abs_ts;
+          call_value->rep_frame=0;
+          call_value->max_ptr=0;
+          call_value->se_data = NULL;
+          call_value->private_data = NULL;
+          call_value->pol = NULL;
+          g_hash_table_insert (dcerpc_cn_calls, call_key, call_value);
+
+          new_matched_key = se_alloc(sizeof (dcerpc_matched_key));
+          *new_matched_key = matched_key;
+          g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
+          value = call_value;  
+        } 
+      }
+    }
+    if (value) {
+      dcerpc_info *di;
+      di=get_next_di();
+      /* handoff this call */
+      di->conv = conv;
+      di->call_id = hdr->call_id;
+      di->smb_fid = dcerpc_get_transport_salt(pinfo);
+      di->ptype = PDU_REQ;
+      di->call_data = value;
+      di->hf_index = -1;
+
+      if(value->rep_frame!=0){
+        pi = proto_tree_add_uint(dcerpc_tree, hf_dcerpc_response_in,
+            tvb, 0, 0, value->rep_frame);
         PROTO_ITEM_SET_GENERATED(pi);
         if(parent_pi != NULL) {
             proto_item_append_text(parent_pi, ", [Resp: #%u]", value->rep_frame);
         }
-           }
-
-           dissect_dcerpc_cn_stub (tvb, offset, pinfo, dcerpc_tree, tree,
-                                   hdr, di, &auth_info, alloc_hint,
-                                   value->req_frame);
-        } else {
-        /* no bind information, simply show stub data */
-        pi = proto_tree_add_text(dcerpc_tree, tvb, offset, 0, "No bind info for this interface Context ID - capture start too late?");
-        PROTO_ITEM_SET_GENERATED(pi);
-           expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u",
-            ctx_id);
-           show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
-        }
+      }
+      dissect_dcerpc_cn_stub (tvb, offset, pinfo, dcerpc_tree, tree,
+            hdr, di, &auth_info, alloc_hint,
+            value->req_frame);
+    } 
+    else {
+      /* no bind information, simply show stub data */
+      pi = proto_tree_add_text(dcerpc_tree, tvb, offset, 0, "No bind info for this interface Context ID - capture start too late?");
+      PROTO_ITEM_SET_GENERATED(pi);
+      expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u",
+          ctx_id);
+      show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
     }
-
-    /* Dissect the verifier */
-    dissect_dcerpc_verifier (tvb, pinfo, dcerpc_tree, hdr, &auth_info);
+  }
+  /* Dissect the verifier */
+  dissect_dcerpc_verifier (tvb, pinfo, dcerpc_tree, hdr, &auth_info);
 
 }
 
@@ -3419,6 +3440,16 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
         proto_item_append_text(parent_pi, " Ctx: %u", ctx_id);
     }
 
+    if (check_col (pinfo->cinfo, COL_DCE_CTX)) {
+                 if(pinfo->dcectxid == 0) {
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "%u", ctx_id);
+               } else {
+                       /* this is not the first DCE-RPC request/response in this (TCP?-)PDU,
+                        * prepend a delimiter */
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
+               }
+    }
+
     /* save context ID for use with dcerpc_add_conv_to_bind_table() */
     pinfo->dcectxid = ctx_id;
 
@@ -3444,92 +3475,89 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
         /* no point in creating one here, really */
         show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
     } else {
-       dcerpc_matched_key matched_key, *new_matched_key;
+           dcerpc_matched_key matched_key, *new_matched_key;
 
        /* !!! we can NOT check flags.visited here since this will interact
           badly with when SMB handles (i.e. calls the subdissector)
           and desegmented pdu's .
           Instead we check if this pdu is already in the matched table or not
        */
-       matched_key.frame = pinfo->fd->num;
-       matched_key.call_id = hdr->call_id;
-       value=g_hash_table_lookup(dcerpc_matched, &matched_key);
-       if(!value){
-               dcerpc_cn_call_key call_key;
-               dcerpc_call_value *call_value;
-
-               call_key.conv=conv;
-               call_key.call_id=hdr->call_id;
-               call_key.smb_fid=dcerpc_get_transport_salt(pinfo);
-
-               if((call_value=g_hash_table_lookup(dcerpc_cn_calls, &call_key))){
+           matched_key.frame = pinfo->fd->num;
+           matched_key.call_id = hdr->call_id;
+           value=g_hash_table_lookup(dcerpc_matched, &matched_key);
+           if(!value){
+                   dcerpc_cn_call_key call_key;
+                   dcerpc_call_value *call_value;
+
+                   call_key.conv=conv;
+                   call_key.call_id=hdr->call_id;
+                   call_key.smb_fid=dcerpc_get_transport_salt(pinfo);
+
+                   if((call_value=g_hash_table_lookup(dcerpc_cn_calls, &call_key))){
                        /* extra sanity check,  only match them if the reply
                           came after the request */
-                       if(call_value->req_frame<pinfo->fd->num){
-                               new_matched_key = se_alloc(sizeof (dcerpc_matched_key));
-                               *new_matched_key = matched_key;
-                               g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
-                               value = call_value;
-                               if(call_value->rep_frame==0){
-                                       call_value->rep_frame=pinfo->fd->num;
-                               }
-                       }
-               }
-       }
+                           if(call_value->req_frame<pinfo->fd->num){
+                                   new_matched_key = se_alloc(sizeof (dcerpc_matched_key));
+                                   *new_matched_key = matched_key;
+                                   g_hash_table_insert (dcerpc_matched, new_matched_key, call_value);
+                                   value = call_value;
+                                   if(call_value->rep_frame==0) {
+                                           call_value->rep_frame=pinfo->fd->num;
+                                   }
+                           }
+                   }
+           }
 
-        if (value) {
-            dcerpc_info *di;
+      if (value) {
+        dcerpc_info *di;
 
-            di=get_next_di();
-            /* handoff this call */
-           di->conv = conv;
-           di->call_id = hdr->call_id;
-           di->smb_fid = dcerpc_get_transport_salt(pinfo);
-           di->ptype = PDU_RESP;
-           di->call_data = value;
+        di=get_next_di();
+        /* handoff this call */
+             di->conv = conv;
+             di->call_id = hdr->call_id;
+             di->smb_fid = dcerpc_get_transport_salt(pinfo);
+             di->ptype = PDU_RESP;
+             di->call_data = value;
 
-           proto_tree_add_uint (dcerpc_tree, hf_dcerpc_opnum, tvb, 0, 0, value->opnum);
+             proto_tree_add_uint (dcerpc_tree, hf_dcerpc_opnum, tvb, 0, 0, value->opnum);
 
         /* (optional) "Object UUID" from request */
         if (value && dcerpc_tree && memcmp(&value->object_uuid, &obj_id_null, sizeof(obj_id_null)) != 0) {
-                pi = proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
-                                              offset, 0, (e_guid_t *) &value->object_uuid, "Object UUID: %s",
-                                              guid_to_str((e_guid_t *) &value->object_uuid));
-                PROTO_ITEM_SET_GENERATED(pi);
+          pi = proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
+                offset, 0, (e_guid_t *) &value->object_uuid, "Object UUID: %s",
+                guid_to_str((e_guid_t *) &value->object_uuid));
+          PROTO_ITEM_SET_GENERATED(pi);
         }
 
         /* request in */
-           if(value->req_frame!=0){
-               nstime_t delta_ts;
-               pi = proto_tree_add_uint(dcerpc_tree, hf_dcerpc_request_in,
+             if(value->req_frame!=0) {
+                     nstime_t delta_ts;
+                     pi = proto_tree_add_uint(dcerpc_tree, hf_dcerpc_request_in,
                                    tvb, 0, 0, value->req_frame);
-        PROTO_ITEM_SET_GENERATED(pi);
-        if(parent_pi != NULL) {
+          PROTO_ITEM_SET_GENERATED(pi);
+          if(parent_pi != NULL) {
             proto_item_append_text(parent_pi, ", [Req: #%u]", value->req_frame);
-        }
-               nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &value->req_time);
-               pi = proto_tree_add_time(dcerpc_tree, hf_dcerpc_time, tvb, offset, 0, &delta_ts);
-        PROTO_ITEM_SET_GENERATED(pi);
+          }
+                     nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &value->req_time);
+                     pi = proto_tree_add_time(dcerpc_tree, hf_dcerpc_time, tvb, offset, 0, &delta_ts);
+          PROTO_ITEM_SET_GENERATED(pi);
         } else {
-                   pi = proto_tree_add_text(dcerpc_tree,
+                     pi = proto_tree_add_text(dcerpc_tree,
                                        tvb, 0, 0, "No request to this DCE/RPC call found");
-                   expert_add_info_format(pinfo, pi, PI_SEQUENCE, PI_NOTE,
+                     expert_add_info_format(pinfo, pi, PI_SEQUENCE, PI_NOTE,
                            "No request to this DCE/RPC call found");
-           }
+             }
 
-           dissect_dcerpc_cn_stub (tvb, offset, pinfo, dcerpc_tree, tree,
-                                   hdr, di, &auth_info, alloc_hint,
-                                   value->rep_frame);
-        } else {
+             dissect_dcerpc_cn_stub (tvb, offset, pinfo, dcerpc_tree, tree,
+                                   hdr, di, &auth_info, alloc_hint,value->rep_frame);
+      } else {
             /* no bind information, simply show stub data */
-            pi = proto_tree_add_text(dcerpc_tree, tvb, offset, 0, "No bind info for this interface Context ID - capture start too late?");
-            PROTO_ITEM_SET_GENERATED(pi);
-               expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u",
-                ctx_id);
-            show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
-        }
+        pi = proto_tree_add_text(dcerpc_tree, tvb, offset, 0, "No bind info for this interface Context ID - capture start too late?");
+        PROTO_ITEM_SET_GENERATED(pi);
+             expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u",ctx_id);
+        show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
+      }
     }
-
     /* Dissect the verifier */
     dissect_dcerpc_verifier (tvb, pinfo, dcerpc_tree, hdr, &auth_info);
 }
@@ -4960,6 +4988,7 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     conv = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
                               pinfo->srcport, pinfo->destport, 0);
     if (!conv) {
+        fprintf(stderr,"Creating a new conv on packet %d\n",pinfo->fd->num);
         conv = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
                                  pinfo->srcport, pinfo->destport, 0);
     }