Note in a comment that the display filter code has its own mechanism for
[obnox/wireshark/wip.git] / packet-dcerpc-lsa.c
index 75335632e262af1cd3a220d9080817bf37ee47b0..1a7a6c554bc8a97a638584ba6a53caf90b8b0d9d 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright 2001, Tim Potter <tpot@samba.org>
  *  2002  Added LSA command dissectors  Ronnie Sahlberg
  *
- * $Id: packet-dcerpc-lsa.c,v 1.16 2002/04/17 15:39:27 sahlberg Exp $
+ * $Id: packet-dcerpc-lsa.c,v 1.28 2002/04/28 10:33:30 sahlberg Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -43,11 +43,13 @@ static int proto_dcerpc_lsa = -1;
 static int hf_lsa_rc = -1;
 static int hf_lsa_hnd = -1;
 static int hf_lsa_server = -1;
+static int hf_lsa_controller = -1;
 static int hf_lsa_obj_attr = -1;
 static int hf_lsa_obj_attr_len = -1;
 static int hf_lsa_obj_attr_name = -1;
 static int hf_lsa_access_mask = -1;
 static int hf_lsa_info_level = -1;
+static int hf_lsa_trusted_info_level = -1;
 static int hf_lsa_sd_size = -1;
 static int hf_lsa_qos_len = -1;
 static int hf_lsa_qos_impersonation_level = -1;
@@ -76,13 +78,17 @@ static int hf_lsa_quota_max_wss = -1;
 static int hf_lsa_quota_pagefile = -1;
 static int hf_lsa_mod_seq_no = -1;
 static int hf_lsa_mod_mtime = -1;
+static int hf_lsa_cur_mtime = -1;
+static int hf_lsa_old_mtime = -1;
 static int hf_lsa_name = -1;
+static int hf_lsa_flat_name = -1;
 static int hf_lsa_forest = -1;
 static int hf_lsa_info_type = -1;
 static int hf_lsa_old_pwd = -1;
 static int hf_lsa_new_pwd = -1;
 static int hf_lsa_sid_type = -1;
 static int hf_lsa_rid = -1;
+static int hf_lsa_rid_offset = -1;
 static int hf_lsa_num_mapped = -1;
 static int hf_lsa_policy_information_class = -1;
 static int hf_lsa_secret = -1;
@@ -90,6 +96,19 @@ static int hf_nt_luid_high = -1;
 static int hf_nt_luid_low = -1;
 static int hf_lsa_privilege_name = -1;
 static int hf_lsa_attr = -1;
+static int hf_lsa_resume_handle = -1;
+static int hf_lsa_trust_direction = -1;
+static int hf_lsa_trust_type = -1;
+static int hf_lsa_trust_attr = -1;
+static int hf_lsa_trust_attr_non_trans = -1;
+static int hf_lsa_trust_attr_uplevel_only = -1;
+static int hf_lsa_trust_attr_tree_parent = -1;
+static int hf_lsa_trust_attr_tree_root = -1;
+static int hf_lsa_auth_update = -1;
+static int hf_lsa_auth_type = -1;
+static int hf_lsa_auth_len = -1;
+static int hf_lsa_auth_blob = -1;
+static int hf_lsa_rights = -1;
 
 static int hf_lsa_unknown_hyper = -1;
 static int hf_lsa_unknown_long = -1;
@@ -118,13 +137,40 @@ static gint ett_lsa_translated_names = -1;
 static gint ett_lsa_translated_name = -1;
 static gint ett_lsa_referenced_domain_list = -1;
 static gint ett_lsa_trust_information = -1;
+static gint ett_lsa_trust_information_ex = -1;
 static gint ett_LUID = -1;
 static gint ett_LSA_PRIVILEGES = -1;
 static gint ett_LSA_PRIVILEGE = -1;
 static gint ett_LSA_LUID_AND_ATTRIBUTES_ARRAY = -1;
 static gint ett_LSA_LUID_AND_ATTRIBUTES = -1;
+static gint ett_LSA_TRUSTED_DOMAIN_LIST = -1;
+static gint ett_LSA_TRUSTED_DOMAIN = -1;
+static gint ett_LSA_TRANSLATED_SIDS = -1;
+static gint ett_lsa_trusted_domain_info = -1;
+static gint ett_lsa_trust_attr = -1;
+static gint ett_lsa_trusted_domain_auth_information = -1;
+static gint ett_lsa_auth_information = -1;
 
 
+static int
+lsa_dissect_pointer_NTTIME(tvbuff_t *tvb, int offset, 
+                             packet_info *pinfo, proto_tree *tree, 
+                             char *drep)
+{
+       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_nt_NTTIME(tvb, offset, pinfo, tree, drep,
+               di->hf_index);
+
+       return offset;
+}
+
 static int
 lsa_dissect_pointer_UNICODE_STRING(tvbuff_t *tvb, int offset, 
                              packet_info *pinfo, proto_tree *tree, 
@@ -209,6 +255,28 @@ lsa_dissect_LSA_SECRET(tvbuff_t *tvb, int offset,
        return offset;
 }
 
+static int
+lsa_dissect_LSA_SECURITY_DESCRIPTOR_data(tvbuff_t *tvb, int offset, 
+                             packet_info *pinfo, proto_tree *tree,
+                             char *drep)
+{
+       guint32 len;
+       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, tree, drep,
+                                    hf_lsa_sd_size, &len);
+
+       dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
+       offset += len;
+
+       return offset;
+}
 int
 lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvbuff_t *tvb, int offset,
                        packet_info *pinfo, proto_tree *parent_tree,
@@ -224,7 +292,12 @@ lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvbuff_t *tvb, int offset,
                tree = proto_item_add_subtree(item, ett_LSA_SECURITY_DESCRIPTOR);
        }
 
-       offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, 0);
+       offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                   hf_lsa_sd_size, NULL);
+
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       lsa_dissect_LSA_SECURITY_DESCRIPTOR_data, NDR_POINTER_UNIQUE,
+                       "LSA SECURITY DESCRIPTOR data:", -1, 0);
 
        proto_item_set_len(item, offset-old_offset);
        return offset;
@@ -240,7 +313,7 @@ lsa_dissect_LPSTR(tvbuff_t *tvb, int offset,
        return offset;
 }
 
-static const value_string lsa_impersionation_level_vals[] = {
+static const value_string lsa_impersonation_level_vals[] = {
        {0,     "Anonymous"},
        {1,     "Identification"},
        {2,     "Impersonation"},
@@ -287,8 +360,9 @@ static int
 lsa_dissect_LSA_HANDLE(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
-       offset = dissect_ndr_ctx_hnd (tvb, offset, pinfo, tree, drep,
+       offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
                        hf_lsa_hnd, NULL);
+
        return offset;
 }
 
@@ -362,13 +436,24 @@ lsa_dissect_lsaclose_reply(tvbuff_t *tvb, int offset,
        return offset;
 }
 
+/* A bug in the NT IDL for lsa openpolicy only stores the first (wide)
+   character of the server name which is always '\'.  This is fixed in lsa
+   openpolicy2 but the function remains for backwards compatibility. */
+
+static int dissect_lsa_openpolicy_server(tvbuff_t *tvb, int offset, 
+                                            packet_info *pinfo, 
+                                            proto_tree *tree, char *drep)
+{
+       return dissect_ndr_uint16(tvb, offset, pinfo, tree, drep, 
+                                 hf_lsa_server, NULL);
+}
 
 static int
 lsa_dissect_lsaopenpolicy_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
-               dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
+               dissect_lsa_openpolicy_server, NDR_POINTER_UNIQUE,
                "Server:", hf_lsa_server, 0);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -400,7 +485,7 @@ lsa_dissect_lsaopenpolicy2_rqst(tvbuff_t *tvb, int offset,
 {
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                dissect_ndr_nt_UNICODE_STRING_str, NDR_POINTER_UNIQUE,
-               "Server:", hf_lsa_server, 0);
+               "Server", hf_lsa_server, 0);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                lsa_dissect_LSA_OBJECT_ATTRIBUTES, NDR_POINTER_REF,
@@ -688,11 +773,11 @@ lsa_dissect_POLICY_DEFAULT_QUOTA_INFO(tvbuff_t *tvb, int offset,
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                                      hf_lsa_quota_max_wss, NULL);
 
-       /* unknown */
+       /* pagefile */
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
-                                     hf_lsa_unknown_long, NULL);
+                                     hf_lsa_quota_pagefile, NULL);
 
-       /* pagefile */
+       /*  */
         offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
                                      hf_lsa_unknown_hyper, NULL);
 
@@ -1150,6 +1235,204 @@ lsa_dissect_LSA_TRUST_INFORMATION(tvbuff_t *tvb, int offset,
        return offset;
 }
 
+static const value_string trusted_direction_vals[] = {
+       {0,     "Trust disabled"},
+       {1,     "Inbound trust"},
+       {2,     "Outbound trust"},
+       {0,     NULL}
+};
+
+static const value_string trusted_type_vals[] = {
+       {1,     "Downlevel"},
+       {2,     "Uplevel"},
+       {3,     "MIT"},
+       {4,     "DCE"},
+       {0,     NULL}
+};
+
+static const true_false_string tfs_trust_attr_non_trans = {
+       "NON TRANSITIVE is set",
+       "Non transitive is NOT set"
+};
+static const true_false_string tfs_trust_attr_uplevel_only = {
+       "UPLEVEL ONLY is set",
+       "Uplevel only is NOT set"
+};
+static const true_false_string tfs_trust_attr_tree_parent = {
+       "TREE PARENT is set",
+       "Tree parent is NOT set"
+};
+static const true_false_string tfs_trust_attr_tree_root = {
+       "TREE ROOT is set",
+       "Tree root is NOT set"
+};
+static int
+lsa_dissect_trust_attr(tvbuff_t *tvb, int offset, packet_info *pinfo, 
+                       proto_tree *parent_tree, char *drep)
+{
+       guint32 mask;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+
+       offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
+                       hf_lsa_trust_attr, &mask);
+
+       if(parent_tree){
+               item = proto_tree_add_uint(parent_tree, hf_lsa_trust_attr,
+                       tvb, offset-4, 4, mask);
+               tree = proto_item_add_subtree(item, ett_lsa_trust_attr);
+       }
+
+       proto_tree_add_boolean(tree, hf_lsa_trust_attr_tree_root,
+               tvb, offset-4, 4, mask);
+       proto_tree_add_boolean(tree, hf_lsa_trust_attr_tree_parent,
+               tvb, offset-4, 4, mask);
+       proto_tree_add_boolean(tree, hf_lsa_trust_attr_uplevel_only,
+               tvb, offset-4, 4, mask);
+       proto_tree_add_boolean(tree, hf_lsa_trust_attr_non_trans,
+               tvb, offset-4, 4, mask);
+
+       return offset;
+}
+
+static int
+lsa_dissect_LSA_TRUST_INFORMATION_EX(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *parent_tree, char *drep)
+{
+       proto_item *item=NULL;
+       proto_tree *tree=NULL;
+       int old_offset=offset;
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, -1,
+                       "TRUST INFORMATION EX:");
+               tree = proto_item_add_subtree(item, ett_lsa_trust_information_ex);
+       }
+
+       /* name */
+       offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
+               hf_lsa_name, 0);
+
+       /* flat name */
+       offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
+               hf_lsa_flat_name, 0);
+
+       /* sid */
+       offset = dissect_ndr_nt_PSID(tvb, offset,
+               pinfo, tree, drep);
+
+       /* direction */
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_trust_direction, NULL);
+
+       /* type */
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_trust_type, NULL);
+       
+       /* attributes */
+       offset = lsa_dissect_trust_attr(tvb, offset, pinfo, tree, drep);
+
+       proto_item_set_len(item, offset-old_offset);
+       return offset;
+}
+
+static int
+lsa_dissect_auth_info_blob(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       dcerpc_info *di;
+       guint32 len;
+
+       di=pinfo->private_data;
+       if(di->conformant_run){
+               /*just a run to handle conformant arrays, nothing to dissect */
+               return offset;
+       }
+
+       /* len */
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_auth_len, &len);
+
+       proto_tree_add_item(tree, hf_lsa_auth_blob, tvb, offset, len, FALSE);
+       offset += len;
+
+       return offset;
+}
+
+static int
+lsa_dissect_auth_info(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *parent_tree, char *drep)
+{
+       proto_item *item=NULL;
+       proto_tree *tree=NULL;
+       int old_offset=offset;
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, -1,
+                       "AUTH INFORMATION:");
+               tree = proto_item_add_subtree(item, ett_lsa_auth_information);
+       }
+
+       /* update */
+        offset = dissect_ndr_uint64 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_auth_update, NULL);
+
+       /* type */
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_auth_type, NULL);
+
+       /* len */
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_auth_len, NULL);
+
+       /* auth info blob */
+        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       lsa_dissect_auth_info_blob, NDR_POINTER_UNIQUE,
+                       "AUTH INFO blob:", -1, 0);
+
+       proto_item_set_len(item, offset-old_offset);
+       return offset;
+}
+
+static int
+lsa_dissect_LSA_TRUSTED_DOMAIN_AUTH_INFORMATION(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *parent_tree, char *drep)
+{
+       proto_item *item=NULL;
+       proto_tree *tree=NULL;
+       int old_offset=offset;
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, -1,
+                       "TRUSTED DOMAIN AUTH INFORMATION:");
+               tree = proto_item_add_subtree(item, ett_lsa_trusted_domain_auth_information);
+       }
+
+       /* unknown */
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_unknown_long, NULL);
+
+       /* unknown */
+       offset = lsa_dissect_auth_info(tvb, offset, pinfo, tree, drep);
+
+       /* unknown */
+       offset = lsa_dissect_auth_info(tvb, offset, pinfo, tree, drep);
+
+       /* unknown */
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_unknown_long, NULL);
+
+       /* unknown */
+       offset = lsa_dissect_auth_info(tvb, offset, pinfo, tree, drep);
+
+       /* unknown */
+       offset = lsa_dissect_auth_info(tvb, offset, pinfo, tree, drep);
+
+       proto_item_set_len(item, offset-old_offset);
+       return offset;
+}
+
+
 static int
 lsa_dissect_LSA_TRUST_INFORMATION_array(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
@@ -1756,84 +2039,775 @@ lsa_dissect_lsaremoveprivilegesfromaccount_reply(tvbuff_t *tvb, int offset,
        return offset;
 }
 
+static int
+lsa_dissect_lsaenumerateaccounts_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
 
+       /* [in,out, ref] LSA_ENUMERATION_HANDLE *resume_hnd */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_resume_handle, NULL);
 
-static dcerpc_sub_dissector dcerpc_lsa_dissectors[] = {
-       { LSA_LSACLOSE, "LSACLOSE",
-               lsa_dissect_lsaclose_rqst,
-               lsa_dissect_lsaclose_reply },
-       { LSA_LSADELETE, "LSADELETE",
-               lsa_dissect_lsadelete_rqst,
-               lsa_dissect_lsadelete_reply },
-       { LSA_LSAENUMERATEPRIVILEGES, "LSAENUMERATEPRIVILEGES",
-               lsa_dissect_lsaenumerateprivileges_rqst,
-               lsa_dissect_lsaenumerateprivileges_reply },
-       { LSA_LSAQUERYSECURITYOBJECT, "LSAQUERYSECURITYOBJECT",
-               lsa_dissect_lsaquerysecurityobject_rqst,
-               lsa_dissect_lsaquerysecurityobject_reply },
-       { LSA_LSASETSECURITYOBJECT, "LSASETSECURITYOBJECT",
-               lsa_dissect_lsasetsecurityobject_rqst,
-               lsa_dissect_lsasetsecurityobject_reply },
-       { LSA_LSACHANGEPASSWORD, "LSACHANGEPASSWORD",
-               lsa_dissect_lsachangepassword_rqst,
-               lsa_dissect_lsachangepassword_reply },
-       { LSA_LSAOPENPOLICY, "LSAOPENPOLICY",
-               lsa_dissect_lsaopenpolicy_rqst,
-               lsa_dissect_lsaopenpolicy_reply },
-       { LSA_LSAQUERYINFORMATIONPOLICY, "LSAQUERYINFORMATIONPOLICY",
-               lsa_dissect_lsaqueryinformationpolicy_rqst,
-               lsa_dissect_lsaqueryinformationpolicy_reply },
-       { LSA_LSASETINFORMATIONPOLICY, "LSASETINFORMATIONPOLICY",
-               lsa_dissect_lsasetinformationpolicy_rqst,
-               lsa_dissect_lsasetinformationpolicy_reply },
-       { LSA_LSACLEARAUDITLOG, "LSACLEARAUDITLOG",
-               lsa_dissect_lsaclearauditlog_rqst,
-               lsa_dissect_lsaclearauditlog_reply },
-       { LSA_LSACREATEACCOUNT, "LSACREATEACCOUNT",
-               NULL, NULL },
-#ifdef REMOVED
-               lsa_dissect_lsacreateaccount_rqst,
-               lsa_dissect_lsacreateaccount_reply },
-#endif
-       { LSA_LSAENUMERATEACCOUNTS, "LSAENUMERATEACCOUNTS",
-               NULL, NULL },
-#ifdef REMOVED
-               lsa_dissect_lsaenumerateaccounts_rqst,
-               lsa_dissect_lsaenumerateaccounts_reply },
-#endif
-       { LSA_LSACREATETRUSTEDDOMAIN, "LSACREATETRUSTEDDOMAIN",
-               NULL, NULL },
-#ifdef REMOVED
-               lsa_dissect_lsacreatetrusteddomain_rqst,
-               lsa_dissect_lsacreatetrusteddomain_reply },
-#endif
-       { LSA_LSAENUMERATETRUSTEDDOMAINS, "LSAENUMERATETRUSTEDDOMAINS",
-               NULL, NULL },
-#ifdef REMOVED
-               lsa_dissect_lsaenumeratetrusteddomains_rqst,
-               lsa_dissect_lsaenumeratetrusteddomains_reply },
-#endif
-       { LSA_LSALOOKUPNAMES, "LSALOOKUPNAMES",
-               NULL, NULL },
-#ifdef REMOVED
-               lsa_dissect_lsalookupnames_rqst,
-               lsa_dissect_lsalookupnames_reply },
-#endif
-       { LSA_LSALOOKUPSIDS, "LSALOOKUPSIDS",
-               lsa_dissect_lsalookupsids_rqst,
-               lsa_dissect_lsalookupsids_reply },
-       { LSA_LSACREATESECRET, "LSACREATESECRET",
-               NULL, NULL },
-#ifdef REMOVED
-               lsa_dissect_lsacreatesecret_rqst,
-               lsa_dissect_lsacreatesecret_reply },
-#endif
-       { LSA_LSAOPENACCOUNT, "LSAOPENACCOUNT",
-               NULL, NULL },
-#ifdef REMOVED
-               lsa_dissect_lsaopenaccount_rqst,
-               lsa_dissect_lsaopenaccount_reply },
-#endif
+       /* [in] ULONG pref_maxlen */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_max_count, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsaenumerateaccounts_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in,out, ref] LSA_ENUMERATION_HANDLE *resume_hnd */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_resume_handle, NULL);
+
+       /* [out, ref] PSID_ARRAY **accounts */
+        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
+                       "", -1, 0);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsacreatetrusteddomain_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd_pol */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in, ref] LSA_TRUST_INFORMATION *domain */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_TRUST_INFORMATION, NDR_POINTER_REF,
+               "LSA_TRUST_INFORMATION pointer: domain", -1, 0);
+
+       /* [in] ACCESS_MASK access */
+       offset = lsa_dissect_ACCESS_MASK(tvb, offset,
+               pinfo, tree, drep);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsacreatetrusteddomain_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [out] LSA_HANDLE *hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsaenumeratetrusteddomains_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in, out, ref] LSA_ENUMERATION_HANDLE *resume_hnd */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_resume_handle, NULL);
+
+       /* [in] ULONG pref_maxlen */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_max_count, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_LSA_TRUSTED_DOMAIN(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *parent_tree, char *drep)
+{
+       proto_item *item=NULL;
+       proto_tree *tree=NULL;
+       int old_offset=offset;
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, 0,
+                       "TRUSTED_DOMAIN:");
+               tree = proto_item_add_subtree(item, ett_LSA_TRUSTED_DOMAIN);
+       }
+
+       /* domain */
+       offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
+               hf_lsa_domain, 0);
+
+       /* sid */
+       offset = dissect_ndr_nt_PSID(tvb, offset,
+               pinfo, tree, drep);
+
+       proto_item_set_len(item, offset-old_offset);
+       return offset;
+}
+
+static int
+lsa_dissect_LSA_TRUSTED_DOMAIN_array(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_TRUSTED_DOMAIN);
+
+       return offset;
+}
+
+static int
+lsa_dissect_LSA_TRUSTED_DOMAIN_LIST(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *parent_tree, char *drep)
+{
+       proto_item *item=NULL;
+       proto_tree *tree=NULL;
+       int old_offset=offset;
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, 0,
+                       "TRUSTED_DOMAIN_LIST:");
+               tree = proto_item_add_subtree(item, ett_LSA_TRUSTED_DOMAIN_LIST);
+       }
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_count, NULL);
+
+       /* privileges */
+        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_TRUSTED_DOMAIN_array, NDR_POINTER_UNIQUE,
+               "TRUSTED_DOMAIN array:", -1, 0);
+
+       proto_item_set_len(item, offset-old_offset);
+       return offset;
+}
+
+static int
+lsa_dissect_lsaenumeratetrusteddomains_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in, out, ref] LSA_ENUMERATION_HANDLE *resume_hnd */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_resume_handle, NULL);
+
+       /* [out, ref] LSA_REFERENCED_DOMAIN_LIST *domains */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_TRUSTED_DOMAIN_LIST, NDR_POINTER_REF,
+               "LSA_TRUSTED_DOMAIN_LIST pointer: domains", -1, 0);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_LSA_UNICODE_STRING_item(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       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_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
+                       di->hf_index, di->levels);
+
+       return offset;
+}
+
+static int
+lsa_dissect_LSA_UNICODE_STRING_array(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_UNICODE_STRING_item);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_LSA_TRANSLATED_SID(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* sid type */
+       offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
+                       hf_lsa_sid_type, NULL);
+
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_rid, NULL);
+
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_index, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_LSA_TRANSLATED_SIDS_array(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_TRANSLATED_SID);
+
+       return offset;
+}
+
+static int
+lsa_dissect_LSA_TRANSLATED_SIDS(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *parent_tree, char *drep)
+{
+       proto_item *item=NULL;
+       proto_tree *tree=NULL;
+       int old_offset=offset;
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, -1,
+                       "LSA_TRANSLATED_SIDS:");
+               tree = proto_item_add_subtree(item, ett_LSA_TRANSLATED_SIDS);
+       }
+
+       /* count */
+        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_count, NULL);
+
+       /* settings */
+        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_TRANSLATED_SIDS_array, NDR_POINTER_UNIQUE,
+               "Translated SIDS", -1, 0);
+
+       proto_item_set_len(item, offset-old_offset);
+       return offset;
+}
+
+static int
+lsa_dissect_lsalookupnames_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in] ULONG count */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_count, NULL);
+
+       /* [in, size_is(count), ref] LSA_UNICODE_STRING *names */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_UNICODE_STRING_array, NDR_POINTER_REF,
+               "Account pointer: names", hf_lsa_acct, 0);
+
+       /* [in, out, ref] LSA_TRANSLATED_SIDS *rids */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_TRANSLATED_SIDS, NDR_POINTER_REF,
+               "LSA_TRANSLATED_SIDS pointer: rids", -1, 0);
+
+       /* [in] USHORT level */
+       offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+               hf_lsa_info_level, NULL);
+
+       /* [in, out, ref] ULONG *num_mapped */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_num_mapped, NULL);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_lsalookupnames_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [out, ref] LSA_REFERENCED_DOMAIN_LIST *domains */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_REFERENCED_DOMAIN_LIST, NDR_POINTER_REF,
+               "LSA_REFERENCED_DOMAIN_LIST pointer: domains", -1, 0);
+
+       /* [in, out, ref] LSA_TRANSLATED_SIDS *rids */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_TRANSLATED_SIDS, NDR_POINTER_REF,
+               "LSA_TRANSLATED_SIDS pointer: rids", -1, 0);
+
+       /* [in, out, ref] ULONG *num_mapped */
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_num_mapped, NULL);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsacreatesecret_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd_pol */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in, ref] LSA_UNICODE_STRING *name */
+       offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
+               hf_lsa_name, 0);
+
+       /* [in] ACCESS_MASK access */
+       offset = lsa_dissect_ACCESS_MASK(tvb, offset,
+               pinfo, tree, drep);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsacreatesecret_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+
+       /* [out] LSA_HANDLE *hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsaopenaccount_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd_pol */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in, ref] SID *account */
+       offset = dissect_ndr_nt_SID(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in] ACCESS_MASK access */
+       offset = lsa_dissect_ACCESS_MASK(tvb, offset,
+               pinfo, tree, drep);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_lsaopenaccount_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [out] LSA_HANDLE *hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static const value_string trusted_info_level_vals[] = {
+       {1,     "Domain Name Information"},
+       {2,     "Controllers Information"},
+       {3,     "Posix Offset Information"},
+       {4,     "Password Information"},
+       {5,     "Domain Information Basic"},
+       {6,     "Domain Information Ex"},
+       {7,     "Domain Auth Information"},
+       {8,     "Domain Full Information"},
+       {9,     "Domain Security Descriptor"},
+       {10,    "Domain Private Information"},
+       {0,     NULL}
+};
+
+static int
+lsa_dissect_TRUSTED_DOMAIN_INFORMATION(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *parent_tree, char *drep)
+{
+       proto_item *item=NULL;
+       proto_tree *tree=NULL;
+       int old_offset=offset;
+       guint16 level;
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, -1,
+                       "TRUSTED_DOMAIN_INFO:");
+               tree = proto_item_add_subtree(item, ett_lsa_trusted_domain_info);
+       }
+
+        offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
+                                     hf_lsa_trusted_info_level, &level);
+
+       ALIGN_TO_4_BYTES;  /* all union arms aligned to 4 bytes, case 7 and 9 need this  */
+       switch(level){
+       case 1: 
+               offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
+                       hf_lsa_domain, 0);
+               break;
+       case 2:
+               offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+                       hf_lsa_count, NULL);
+               offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+                       lsa_dissect_LSA_UNICODE_STRING_array, NDR_POINTER_UNIQUE,
+                       "Controllers pointer: ", hf_lsa_controller, 0);
+               break;
+       case 3:
+               offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                       hf_lsa_rid_offset, NULL);
+               break;
+       case 4:
+               offset = lsa_dissect_LSA_SECRET(tvb, offset, pinfo, tree, drep);
+               offset = lsa_dissect_LSA_SECRET(tvb, offset, pinfo, tree, drep);
+               break;
+       case 5:
+               offset = lsa_dissect_LSA_TRUST_INFORMATION(tvb, offset,
+                       pinfo, tree, drep);
+               break;
+       case 6:
+               offset = lsa_dissect_LSA_TRUST_INFORMATION_EX(tvb, offset,
+                       pinfo, tree, drep);
+               break;
+       case 7:
+               offset = lsa_dissect_LSA_TRUSTED_DOMAIN_AUTH_INFORMATION(tvb, offset, pinfo, tree, drep);
+               break;
+       case 8:
+               offset = lsa_dissect_LSA_TRUST_INFORMATION_EX(tvb, offset,
+                       pinfo, tree, drep);
+               offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                       hf_lsa_rid_offset, NULL);
+               offset = lsa_dissect_LSA_TRUSTED_DOMAIN_AUTH_INFORMATION(tvb, offset, pinfo, tree, drep);
+               break;
+       case 9:
+               offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset, pinfo, tree, drep);
+               break;
+       case 10:
+               offset = lsa_dissect_LSA_TRUST_INFORMATION_EX(tvb, offset,
+                       pinfo, tree, drep);
+               offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
+                       hf_lsa_rid_offset, NULL);
+               offset = lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvb, offset, pinfo, tree, drep);
+               break;
+       }
+
+       proto_item_set_len(item, offset-old_offset);
+       return offset;
+}
+
+static int
+lsa_dissect_lsaqueryinfotrusteddomain_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in] TRUSTED_INFORMATION_CLASS level */
+       offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+               hf_lsa_trusted_info_level, NULL);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_lsaqueryinfotrusteddomain_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [out, ref] TRUSTED_DOMAIN_INFORMATION *info */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_TRUSTED_DOMAIN_INFORMATION, NDR_POINTER_REF,
+               "TRUSTED_DOMAIN_INFORMATION pointer: info", -1, 0);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsasetinformationtrusteddomain_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in] TRUSTED_INFORMATION_CLASS level */
+       offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+               hf_lsa_trusted_info_level, NULL);
+
+       /* [in, ref] TRUSTED_DOMAIN_INFORMATION *info */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_TRUSTED_DOMAIN_INFORMATION, NDR_POINTER_REF,
+               "TRUSTED_DOMAIN_INFORMATION pointer: info", -1, 0);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_lsasetinformationtrusteddomain_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsaopensecret_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd_pol */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in, ref] LSA_UNICODE_STRING *name */
+       offset = dissect_ndr_nt_UNICODE_STRING(tvb, offset, pinfo, tree, drep,
+               hf_lsa_name, 0);
+
+       /* [in] ACCESS_MASK access */
+       offset = lsa_dissect_ACCESS_MASK(tvb, offset,
+               pinfo, tree, drep);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_lsaopensecret_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [out] LSA_HANDLE *hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsasetsecret_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in, unique] LSA_SECRET *new_val */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_SECRET, NDR_POINTER_UNIQUE,
+               "LSA_SECRET pointer: new_val", -1, 0);
+
+       /* [in, unique] LSA_SECRET *old_val */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_SECRET, NDR_POINTER_UNIQUE,
+               "LSA_SECRET pointer: old_val", -1, 0);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_lsasetsecret_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsaquerysecret_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in, out, unique] LSA_SECRET **curr_val */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_SECRET, NDR_POINTER_UNIQUE,
+               "LSA_SECRET pointer: curr_val", -1, 0);
+
+       /* [in, out, unique] LARGE_INTEGER *curr_mtime */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_pointer_NTTIME, NDR_POINTER_UNIQUE,
+               "NTIME pointer: old_mtime", hf_lsa_cur_mtime, 0);
+
+       /* [in, out, unique] LSA_SECRET **old_val */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_SECRET, NDR_POINTER_UNIQUE,
+               "LSA_SECRET pointer: old_val", -1, 0);
+
+       /* [in, out, unique] LARGE_INTEGER *old_mtime */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_pointer_NTTIME, NDR_POINTER_UNIQUE,
+               "NTIME pointer: old_mtime", hf_lsa_old_mtime, 0);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_lsaquerysecret_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in, out, unique] LSA_SECRET **curr_val */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_SECRET, NDR_POINTER_UNIQUE,
+               "LSA_SECRET pointer: curr_val", -1, 0);
+
+       /* [in, out, unique] LARGE_INTEGER *curr_mtime */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_pointer_NTTIME, NDR_POINTER_UNIQUE,
+               "NTIME pointer: old_mtime", hf_lsa_cur_mtime, 0);
+
+       /* [in, out, unique] LSA_SECRET **old_val */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_SECRET, NDR_POINTER_UNIQUE,
+               "LSA_SECRET pointer: old_val", -1, 0);
+
+       /* [in, out, unique] LARGE_INTEGER *old_mtime */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_pointer_NTTIME, NDR_POINTER_UNIQUE,
+               "NTIME pointer: old_mtime", hf_lsa_old_mtime, 0);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsadeleteobject_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       return offset;
+}
+
+
+static int
+lsa_dissect_lsadeleteobject_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsaenumerateaccountswithuserright_rqst(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [in] LSA_HANDLE hnd */
+       offset = lsa_dissect_LSA_HANDLE(tvb, offset,
+               pinfo, tree, drep);
+
+       /* [in, unique] LSA_UNICODE_STRING *rights */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_pointer_UNICODE_STRING, NDR_POINTER_UNIQUE,
+               "LSA_UNICODE_STRING pointer: rights", hf_lsa_rights, 0);
+
+       return offset;
+}
+
+static int
+lsa_dissect_lsaenumerateaccountswithuserright_reply(tvbuff_t *tvb, int offset,
+       packet_info *pinfo, proto_tree *tree, char *drep)
+{
+       /* [out, ref] LSA_UNICODE_STRING_ARRAY *accounts */
+       offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+               lsa_dissect_LSA_UNICODE_STRING_array, NDR_POINTER_REF,
+               "Account pointer: names", hf_lsa_acct, 0);
+
+       offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+               hf_lsa_rc, NULL);
+
+       return offset;
+}
+
+
+
+static dcerpc_sub_dissector dcerpc_lsa_dissectors[] = {
+       { LSA_LSACLOSE, "LSACLOSE",
+               lsa_dissect_lsaclose_rqst,
+               lsa_dissect_lsaclose_reply },
+       { LSA_LSADELETE, "LSADELETE",
+               lsa_dissect_lsadelete_rqst,
+               lsa_dissect_lsadelete_reply },
+       { LSA_LSAENUMERATEPRIVILEGES, "LSAENUMERATEPRIVILEGES",
+               lsa_dissect_lsaenumerateprivileges_rqst,
+               lsa_dissect_lsaenumerateprivileges_reply },
+       { LSA_LSAQUERYSECURITYOBJECT, "LSAQUERYSECURITYOBJECT",
+               lsa_dissect_lsaquerysecurityobject_rqst,
+               lsa_dissect_lsaquerysecurityobject_reply },
+       { LSA_LSASETSECURITYOBJECT, "LSASETSECURITYOBJECT",
+               lsa_dissect_lsasetsecurityobject_rqst,
+               lsa_dissect_lsasetsecurityobject_reply },
+       { LSA_LSACHANGEPASSWORD, "LSACHANGEPASSWORD",
+               lsa_dissect_lsachangepassword_rqst,
+               lsa_dissect_lsachangepassword_reply },
+       { LSA_LSAOPENPOLICY, "LSAOPENPOLICY",
+               lsa_dissect_lsaopenpolicy_rqst,
+               lsa_dissect_lsaopenpolicy_reply },
+       { LSA_LSAQUERYINFORMATIONPOLICY, "LSAQUERYINFORMATIONPOLICY",
+               lsa_dissect_lsaqueryinformationpolicy_rqst,
+               lsa_dissect_lsaqueryinformationpolicy_reply },
+       { LSA_LSASETINFORMATIONPOLICY, "LSASETINFORMATIONPOLICY",
+               lsa_dissect_lsasetinformationpolicy_rqst,
+               lsa_dissect_lsasetinformationpolicy_reply },
+       { LSA_LSACLEARAUDITLOG, "LSACLEARAUDITLOG",
+               lsa_dissect_lsaclearauditlog_rqst,
+               lsa_dissect_lsaclearauditlog_reply },
+       { LSA_LSACREATEACCOUNT, "LSACREATEACCOUNT",
+               NULL, NULL },  /* 0x0a */
+#ifdef REMOVED
+               lsa_dissect_lsacreateaccount_rqst,
+               lsa_dissect_lsacreateaccount_reply },
+#endif
+       { LSA_LSAENUMERATEACCOUNTS, "LSAENUMERATEACCOUNTS",
+               lsa_dissect_lsaenumerateaccounts_rqst,
+               lsa_dissect_lsaenumerateaccounts_reply },
+       { LSA_LSACREATETRUSTEDDOMAIN, "LSACREATETRUSTEDDOMAIN",
+               lsa_dissect_lsacreatetrusteddomain_rqst,
+               lsa_dissect_lsacreatetrusteddomain_reply },
+       { LSA_LSAENUMERATETRUSTEDDOMAINS, "LSAENUMERATETRUSTEDDOMAINS",
+               lsa_dissect_lsaenumeratetrusteddomains_rqst,
+               lsa_dissect_lsaenumeratetrusteddomains_reply },
+       { LSA_LSALOOKUPNAMES, "LSALOOKUPNAMES",
+               lsa_dissect_lsalookupnames_rqst,
+               lsa_dissect_lsalookupnames_reply },
+       { LSA_LSALOOKUPSIDS, "LSALOOKUPSIDS",
+               lsa_dissect_lsalookupsids_rqst,
+               lsa_dissect_lsalookupsids_reply },
+       { LSA_LSACREATESECRET, "LSACREATESECRET",  /*0x10*/
+               lsa_dissect_lsacreatesecret_rqst,
+               lsa_dissect_lsacreatesecret_reply },
+       { LSA_LSAOPENACCOUNT, "LSAOPENACCOUNT",
+               lsa_dissect_lsaopenaccount_rqst,
+               lsa_dissect_lsaopenaccount_reply },
        { LSA_LSAENUMERATEPRIVILEGESACCOUNT, "LSAENUMERATEPRIVILEGESACCOUNT",
                lsa_dissect_lsaenumerateprivilegesaccount_rqst,
                lsa_dissect_lsaenumerateprivilegesaccount_reply },
@@ -1859,35 +2833,20 @@ static dcerpc_sub_dissector dcerpc_lsa_dissectors[] = {
                lsa_dissect_lsaopentrusteddomain_rqst,
                lsa_dissect_lsaopentrusteddomain_reply },
        { LSA_LSAQUERYINFOTRUSTEDDOMAIN, "LSAQUERYINFOTRUSTEDDOMAIN",
-               NULL, NULL },
-#ifdef REMOVED
                lsa_dissect_lsaqueryinfotrusteddomain_rqst,
                lsa_dissect_lsaqueryinfotrusteddomain_reply },
-#endif
        { LSA_LSASETINFORMATIONTRUSTEDDOMAIN, "LSASETINFORMATIONTRUSTEDDOMAIN",
-               NULL, NULL },
-#ifdef REMOVED
                lsa_dissect_lsasetinformationtrusteddomain_rqst,
                lsa_dissect_lsasetinformationtrusteddomain_reply },
-#endif
        { LSA_LSAOPENSECRET, "LSAOPENSECRET",
-               NULL, NULL },
-#ifdef REMOVED
                lsa_dissect_lsaopensecret_rqst,
                lsa_dissect_lsaopensecret_reply },
-#endif
        { LSA_LSASETSECRET, "LSASETSECRET",
-               NULL, NULL },
-#ifdef REMOVED
                lsa_dissect_lsasetsecret_rqst,
                lsa_dissect_lsasetsecret_reply },
-#endif
        { LSA_LSAQUERYSECRET, "LSAQUERYSECRET",
-               NULL, NULL },
-#ifdef REMOVED
                lsa_dissect_lsaquerysecret_rqst,
                lsa_dissect_lsaquerysecret_reply },
-#endif
        { LSA_LSALOOKUPPRIVILEGEVALUE, "LSALOOKUPPRIVILEGEVALUE",
                lsa_dissect_lsalookupprivilegevalue_rqst,
                lsa_dissect_lsalookupprivilegevalue_reply },
@@ -1901,17 +2860,11 @@ static dcerpc_sub_dissector dcerpc_lsa_dissectors[] = {
                lsa_dissect_lsalookupprivilegedisplayname_reply },
 #endif
        { LSA_LSADELETEOBJECT, "LSADELETEOBJECT",
-               NULL, NULL },
-#ifdef REMOVED
                lsa_dissect_lsadeleteobject_rqst,
                lsa_dissect_lsadeleteobject_reply },
-#endif
        { LSA_LSAENUMERATEACCOUNTSWITHUSERRIGHT, "LSAENUMERATEACCOUNTSWITHUSERRIGHT",
-               NULL, NULL },
-#ifdef REMOVED
                lsa_dissect_lsaenumerateaccountswithuserright_rqst,
                lsa_dissect_lsaenumerateaccountswithuserright_reply },
-#endif
        { LSA_LSAENUMERATEACCOUNTRIGHTS, "LSAENUMERATEACCOUNTRIGHTS",
                NULL, NULL },
 #ifdef REMOVED
@@ -2069,6 +3022,10 @@ proto_register_dcerpc_lsa(void)
                { "Server", "lsa.server", FT_STRING, BASE_NONE,
                NULL, 0, "Name of Server", HFILL }},
 
+       { &hf_lsa_controller,
+               { "Controller", "lsa.controller", FT_STRING, BASE_NONE,
+               NULL, 0, "Name of Domain Controller", HFILL }},
+
        { &hf_lsa_unknown_hyper,
                { "Unknown hyper", "lsa.unknown.hyper", FT_UINT64, BASE_HEX, 
                NULL, 0x0, "Unknown hyper. If you know what this is, contact ethereal developers.", HFILL }},
@@ -2109,6 +3066,10 @@ proto_register_dcerpc_lsa(void)
                { "Level", "lsa.info.level", FT_UINT16, BASE_DEC, 
                NULL, 0x0, "Information level of requested data", HFILL }},
 
+       { &hf_lsa_trusted_info_level,
+               { "Info Level", "lsa.trusted.info_level", FT_UINT16, BASE_DEC, 
+               VALS(trusted_info_level_vals), 0x0, "Information level of requested Trusted Domain Information", HFILL }},
+
        { &hf_lsa_sd_size,
                { "Size", "lsa.sd_size", FT_UINT32, BASE_DEC, 
                NULL, 0x0, "Size of lsa security descriptor", HFILL }},
@@ -2118,8 +3079,8 @@ proto_register_dcerpc_lsa(void)
                NULL, 0x0, "Length of quality of service structure", HFILL }},
 
        { &hf_lsa_qos_impersonation_level,
-               { "Impersionation", "lsa.qos.imp_lev", FT_UINT16, BASE_DEC, 
-               VALS(lsa_impersionation_level_vals), 0x0, "QOS Impersionation Level", HFILL }},
+               { "Impersonation level", "lsa.qos.imp_lev", FT_UINT16, BASE_DEC, 
+               VALS(lsa_impersonation_level_vals), 0x0, "QOS Impersonation Level", HFILL }},
 
        { &hf_lsa_qos_track_context,
                { "Context Tracking", "lsa.qos.track_ctx", FT_UINT8, BASE_DEC, 
@@ -2213,10 +3174,22 @@ proto_register_dcerpc_lsa(void)
                { "MTime", "lsa.mod.mtime", FT_ABSOLUTE_TIME, BASE_NONE, 
                NULL, 0x0, "Time when this modification occured", HFILL }},
 
+       { &hf_lsa_cur_mtime,
+               { "Current MTime", "lsa.cur.mtime", FT_ABSOLUTE_TIME, BASE_NONE, 
+               NULL, 0x0, "Current MTime to set", HFILL }},
+
+       { &hf_lsa_old_mtime,
+               { "Old MTime", "lsa.old.mtime", FT_ABSOLUTE_TIME, BASE_NONE, 
+               NULL, 0x0, "Old MTime for this object", HFILL }},
+
        { &hf_lsa_name,
                { "Name", "lsa.name", FT_STRING, BASE_NONE, 
                NULL, 0x0, "", HFILL }},
 
+       { &hf_lsa_flat_name,
+               { "Flat Name", "lsa.flat_name", FT_STRING, BASE_NONE, 
+               NULL, 0x0, "", HFILL }},
+
        { &hf_lsa_forest,
                { "Forest", "lsa.forest", FT_STRING, BASE_NONE, 
                NULL, 0x0, "", HFILL }},
@@ -2241,6 +3214,10 @@ proto_register_dcerpc_lsa(void)
                { "RID", "lsa.rid", FT_UINT32, BASE_HEX, 
                NULL, 0x0, "RID", HFILL }},
 
+       { &hf_lsa_rid_offset,
+               { "RID Offset", "lsa.rid.offset", FT_UINT32, BASE_HEX, 
+               NULL, 0x0, "RID Offset", HFILL }},
+
        { &hf_lsa_index,
                { "Index", "lsa.index", FT_UINT32, BASE_DEC, 
                NULL, 0x0, "", HFILL }},
@@ -2257,6 +3234,10 @@ proto_register_dcerpc_lsa(void)
                { "LSA Secret", "lsa.secret", FT_BYTES, BASE_HEX,
                NULL, 0, "", HFILL }},
 
+       { &hf_lsa_auth_blob,
+               { "Auth blob", "lsa.auth.blob", FT_BYTES, BASE_HEX,
+               NULL, 0, "", HFILL }},
+
        { &hf_nt_luid_high,
                { "High", "nt.luid.high", FT_UINT32, BASE_HEX, 
                NULL, 0x0, "LUID High component", HFILL }},
@@ -2273,11 +3254,59 @@ proto_register_dcerpc_lsa(void)
                { "Name", "lsa.privilege.name", FT_STRING, BASE_NONE, 
                NULL, 0x0, "LSA Privilege Name", HFILL }},
 
+       { &hf_lsa_rights,
+               { "Rights", "lsa.rights", FT_STRING, BASE_NONE, 
+               NULL, 0x0, "Account Rights", HFILL }},
+
        { &hf_lsa_attr,
                { "Attr", "lsa.attr", FT_UINT64, BASE_HEX, 
                NULL, 0x0, "LSA Attributes", HFILL }},
 
-       
+       { &hf_lsa_auth_update,
+               { "Update", "lsa.auth.update", FT_UINT64, BASE_HEX, 
+               NULL, 0x0, "LSA Auth Info update", HFILL }},
+
+       { &hf_lsa_resume_handle,
+               { "Resume Handle", "lsa.resume_handle", FT_UINT32, BASE_DEC, 
+               NULL, 0x0, "Resume Handle", HFILL }},
+
+       { &hf_lsa_trust_direction,
+               { "Trust Direction", "lsa.trust.direction", FT_UINT32, BASE_DEC, 
+               VALS(trusted_direction_vals), 0x0, "Trust direction", HFILL }},
+
+       { &hf_lsa_trust_type,
+               { "Trust Type", "lsa.trust.type", FT_UINT32, BASE_DEC, 
+               VALS(trusted_type_vals), 0x0, "Trust type", HFILL }},
+
+       { &hf_lsa_trust_attr,
+               { "Trust Attr", "lsa.trust.attr", FT_UINT32, BASE_HEX, 
+               NULL, 0x0, "Trust attributes", HFILL }},
+
+       { &hf_lsa_trust_attr_non_trans,
+               { "Non Transitive", "lsa.trust.attr.non_trans", FT_BOOLEAN, 32,
+               TFS(&tfs_trust_attr_non_trans), 0x00000001, "Non Transitive trust", HFILL }},
+
+       { &hf_lsa_trust_attr_uplevel_only,
+               { "Upleve only", "lsa.trust.attr.uplevel_only", FT_BOOLEAN, 32,
+               TFS(&tfs_trust_attr_uplevel_only), 0x00000002, "Uplevel only trust", HFILL }},
+
+       { &hf_lsa_trust_attr_tree_parent,
+               { "Tree Parent", "lsa.trust.attr.tree_parent", FT_BOOLEAN, 32,
+               TFS(&tfs_trust_attr_tree_parent), 0x00400000, "Tree Parent trust", HFILL }},
+
+       { &hf_lsa_trust_attr_tree_root,
+               { "Tree Root", "lsa.trust.attr.tree_root", FT_BOOLEAN, 32,
+               TFS(&tfs_trust_attr_tree_root), 0x00800000, "Tree Root trust", HFILL }},
+
+       { &hf_lsa_auth_type,
+               { "Auth Type", "lsa.auth.type", FT_UINT32, BASE_DEC, 
+               NULL, 0x0, "Auth Info type", HFILL }},
+
+       { &hf_lsa_auth_len,
+               { "Auth Len", "lsa.auth.len", FT_UINT32, BASE_DEC, 
+               NULL, 0x0, "Auth Info len", HFILL }},
+
+
        };
 
         static gint *ett[] = {
@@ -2300,11 +3329,19 @@ proto_register_dcerpc_lsa(void)
                &ett_lsa_translated_name,
                &ett_lsa_referenced_domain_list,
                &ett_lsa_trust_information,
+               &ett_lsa_trust_information_ex,
                &ett_LUID,
                &ett_LSA_PRIVILEGES,
                &ett_LSA_PRIVILEGE,
                &ett_LSA_LUID_AND_ATTRIBUTES_ARRAY,
                &ett_LSA_LUID_AND_ATTRIBUTES,
+               &ett_LSA_TRUSTED_DOMAIN_LIST,
+               &ett_LSA_TRUSTED_DOMAIN,
+               &ett_LSA_TRANSLATED_SIDS,
+               &ett_lsa_trusted_domain_info,
+               &ett_lsa_trust_attr,
+               &ett_lsa_trusted_domain_auth_information,
+               &ett_lsa_auth_information,
         };
 
         proto_dcerpc_lsa = proto_register_protocol(