In the policy handle hashing, handle more than one policy handle having
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 5 Jun 2003 04:22:04 +0000 (04:22 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 5 Jun 2003 04:22:04 +0000 (04:22 +0000)
the same value, as an open might return handle XXX, handle XXX might
then be closed, and a subsequent handle might return handle XXX, and we
want to keep the two handles distinct to avoid, for example, displaying
handles closed before they're opened.

In policy handle open replies, store the handle name only if the
operation succeeded.  We can now do that without parsing the packet
twice.

Have "dissect_nt_policy_hnd()" optionally return, through a pointer, the
protocol tree item for the handle, so that its caller can decorate the
item with the name of the handle - that's done on opens, where we do
that only if the operation succeeds.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@7787 f5534014-38df-0310-8fa8-9805f1628bb7

packet-dcerpc-lsa.c
packet-dcerpc-mapi.c
packet-dcerpc-nt.c
packet-dcerpc-nt.h
packet-dcerpc-reg.c
packet-dcerpc-samr.c
packet-dcerpc-spoolss.c
packet-dcerpc-srvsvc.c
packet-dcerpc-svcctl.c

index e8aec641024c1847f182b50fefb2005168f2c055..f511c4f5b8baf07dd249672e2208ad8226de9e28 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright 2001,2003 Tim Potter <tpot@samba.org>
  *  2002  Added LSA command dissectors  Ronnie Sahlberg
  *
- * $Id: packet-dcerpc-lsa.c,v 1.84 2003/05/30 11:30:09 sahlberg Exp $
+ * $Id: packet-dcerpc-lsa.c,v 1.85 2003/06/05 04:22:02 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -516,7 +516,7 @@ lsa_dissect_lsaclose_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, TRUE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, TRUE);
 
        return offset;
 }
@@ -526,7 +526,7 @@ lsa_dissect_lsaclose_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -569,14 +569,22 @@ lsa_dissect_lsaopenpolicy_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, &policy_hnd, TRUE, FALSE);
-
-       dcerpc_smb_store_pol_name(&policy_hnd, "OpenPolicy handle");
+                       hf_lsa_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(
-               tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
+               tvb, offset, pinfo, tree, drep, hf_lsa_rc, &status);
+
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
+                                         "OpenPolicy handle");
+
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": OpenPolicy handle");
+       }
 
        return offset;
 }
@@ -608,23 +616,30 @@ lsa_dissect_lsaopenpolicy2_reply(tvbuff_t *tvb, int offset,
        dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
        char *pol_name;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, &policy_hnd, TRUE, FALSE);
+                       hf_lsa_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
-       if (dcv->private_data)
-               pol_name = g_strdup_printf(
-                       "OpenPolicy2(%s)", (char *)dcv->private_data);
-       else
-               pol_name = g_strdup("OpenPolicy2 handle");
+       offset = dissect_ntstatus(
+               tvb, offset, pinfo, tree, drep, hf_lsa_rc, &status);
 
-       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+       if (status == 0) {
+               if (dcv->private_data)
+                       pol_name = g_strdup_printf(
+                               "OpenPolicy2(%s)", (char *)dcv->private_data);
+               else
+                       pol_name = g_strdup("OpenPolicy2 handle");
 
-       g_free(pol_name);
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
 
-       offset = dissect_ntstatus(
-               tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": %s", pol_name);
+
+               g_free(pol_name);
+       }
 
        return offset;
 }
@@ -652,7 +667,7 @@ lsa_dissect_lsaqueryinformationpolicy_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
                hf_lsa_policy_information_class, &level);
@@ -1121,7 +1136,7 @@ lsa_dissect_lsadelete_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -1142,7 +1157,7 @@ lsa_dissect_lsaquerysecurityobject_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_lsa_info_type, NULL);
@@ -1171,7 +1186,7 @@ lsa_dissect_lsasetsecurityobject_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_lsa_info_type, NULL);
@@ -1316,7 +1331,7 @@ lsa_dissect_lsalookupsids_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
@@ -1627,7 +1642,7 @@ lsa_dissect_lsasetquotasforaccount_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                lsa_dissect_POLICY_DEFAULT_QUOTA_INFO, NDR_POINTER_REF,
@@ -1653,7 +1668,7 @@ lsa_dissect_lsagetquotasforaccount_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -1679,7 +1694,7 @@ lsa_dissect_lsasetinformationpolicy_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
                hf_lsa_policy_information_class, NULL);
@@ -1708,7 +1723,7 @@ lsa_dissect_lsaclearauditlog_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_nt_SID(tvb, offset,
                pinfo, tree, drep, -1);
@@ -1726,7 +1741,7 @@ lsa_dissect_lsaclearauditlog_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -1739,7 +1754,7 @@ lsa_dissect_lsagetsystemaccessaccount_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -1764,7 +1779,7 @@ lsa_dissect_lsasetsystemaccessaccount_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_lsa_rid, NULL);
@@ -1789,7 +1804,7 @@ lsa_dissect_lsaopentrusteddomain_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_nt_SID(tvb, offset,
                pinfo, tree, drep, -1);
@@ -1806,7 +1821,7 @@ lsa_dissect_lsaopentrusteddomain_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -1820,7 +1835,7 @@ lsa_dissect_lsadeletetrusteddomain_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_nt_SID(tvb, offset,
                pinfo, tree, drep, -1);
@@ -1929,7 +1944,7 @@ lsa_dissect_lsaenumerateprivileges_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                hf_lsa_count, NULL);
@@ -1962,7 +1977,7 @@ lsa_dissect_lsalookupprivilegevalue_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* privilege name */
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -1993,7 +2008,7 @@ lsa_dissect_lsalookupprivilegename_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* LUID */
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -2026,7 +2041,7 @@ lsa_dissect_lsaenumerateprivilegesaccount_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -2114,7 +2129,7 @@ lsa_dissect_lsaaddprivilegestoaccount_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LUID_AND_ATTRIBUTES_ARRAY *privs */
        offset = lsa_dissect_LUID_AND_ATTRIBUTES_ARRAY(tvb, offset,
@@ -2140,7 +2155,7 @@ lsa_dissect_lsaremoveprivilegesfromaccount_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in] char unknown */
        offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
@@ -2171,7 +2186,7 @@ lsa_dissect_lsaenumerateaccounts_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in,out, ref] LSA_ENUMERATION_HANDLE *resume_hnd */
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
@@ -2209,7 +2224,7 @@ lsa_dissect_lsacreatetrusteddomain_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd_pol */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_TRUST_INFORMATION *domain */
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -2229,7 +2244,7 @@ lsa_dissect_lsacreatetrusteddomain_reply(tvbuff_t *tvb, int offset,
 {
        /* [out] LSA_HANDLE *hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -2243,7 +2258,7 @@ lsa_dissect_lsaenumeratetrusteddomains_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, out, ref] LSA_ENUMERATION_HANDLE *resume_hnd */
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
@@ -2443,7 +2458,7 @@ lsa_dissect_lsalookupnames_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in] ULONG count */
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
@@ -2501,7 +2516,7 @@ lsa_dissect_lsacreatesecret_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd_pol */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_UNICODE_STRING *name */
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
@@ -2521,7 +2536,7 @@ lsa_dissect_lsacreatesecret_reply(tvbuff_t *tvb, int offset,
 
        /* [out] LSA_HANDLE *hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -2535,7 +2550,7 @@ lsa_dissect_lsaopenaccount_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd_pol */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] SID *account */
        offset = dissect_ndr_nt_SID(tvb, offset,
@@ -2555,7 +2570,7 @@ lsa_dissect_lsaopenaccount_reply(tvbuff_t *tvb, int offset,
 {
        /* [out] LSA_HANDLE *hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -2656,7 +2671,7 @@ lsa_dissect_lsaqueryinfotrusteddomain_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in] TRUSTED_INFORMATION_CLASS level */
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
@@ -2687,7 +2702,7 @@ lsa_dissect_lsasetinformationtrusteddomain_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in] TRUSTED_INFORMATION_CLASS level */
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
@@ -2718,7 +2733,7 @@ lsa_dissect_lsaopensecret_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd_pol */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_UNICODE_STRING *name */
        offset = dissect_ndr_counted_string_cb(
@@ -2740,7 +2755,7 @@ lsa_dissect_lsaopensecret_reply(tvbuff_t *tvb, int offset,
 {
        /* [out] LSA_HANDLE *hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -2754,7 +2769,7 @@ lsa_dissect_lsasetsecret_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, unique] LSA_SECRET *new_val */
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -2786,7 +2801,7 @@ lsa_dissect_lsaquerysecret_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, out, unique] LSA_SECRET **curr_val */
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -2848,7 +2863,7 @@ lsa_dissect_lsadeleteobject_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -2870,7 +2885,7 @@ lsa_dissect_lsaenumerateaccountswithuserright_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, unique] LSA_UNICODE_STRING *rights */
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -2901,7 +2916,7 @@ lsa_dissect_lsaenumerateaccountrights_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] SID *account */
        offset = dissect_ndr_nt_SID(tvb, offset,
@@ -2932,7 +2947,7 @@ lsa_dissect_lsaaddaccountrights_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] SID *account */
        offset = dissect_ndr_nt_SID(tvb, offset,
@@ -2963,7 +2978,7 @@ lsa_dissect_lsaremoveaccountrights_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] SID *account */
        offset = dissect_ndr_nt_SID(tvb, offset,
@@ -2999,7 +3014,7 @@ lsa_dissect_lsaquerytrusteddomaininfobyname_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE handle */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_UNICODE_STRING *name */
        /* domain */
@@ -3036,7 +3051,7 @@ lsa_dissect_lsasettrusteddomaininfobyname_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE handle */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_UNICODE_STRING *name */
        /* domain */
@@ -3072,7 +3087,7 @@ lsa_dissect_lsaquerytrusteddomaininfo_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE handle */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] SID *sid */
        offset = dissect_ndr_nt_SID(tvb, offset,
@@ -3091,7 +3106,7 @@ lsa_dissect_lsaopentrusteddomainbyname_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE handle */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_UNICODE_STRING *name */
        /* domain */
@@ -3112,7 +3127,7 @@ lsa_dissect_lsaopentrusteddomainbyname_reply(tvbuff_t *tvb, int offset,
 {
        /* [out] LSA_HANDLE handle */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -3143,7 +3158,7 @@ lsa_dissect_lsasettrusteddomaininfo_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE handle */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] SID *sid */
        offset = dissect_ndr_nt_SID(tvb, offset,
@@ -3177,7 +3192,7 @@ lsa_dissect_lsaqueryinformationpolicy2_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
                hf_lsa_policy_information_class, NULL);
@@ -3206,7 +3221,7 @@ lsa_dissect_lsasetinformationpolicy2_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
                hf_lsa_policy_information_class, NULL);
@@ -3233,7 +3248,7 @@ lsa_dissect_lsaquerydomaininformationpolicy_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
                hf_lsa_policy_information_class, NULL);
@@ -3260,7 +3275,7 @@ lsa_dissect_lsasetdomaininformationpolicy_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
                hf_lsa_policy_information_class, NULL);
@@ -3288,7 +3303,7 @@ lsa_dissect_lsalookupnames2_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in] ULONG count */
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
@@ -3355,7 +3370,7 @@ lsa_dissect_lsacreateaccount_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_nt_SID(tvb, offset,
                pinfo, tree, drep, -1);
@@ -3371,7 +3386,7 @@ lsa_dissect_lsacreateaccount_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -3385,7 +3400,7 @@ lsa_dissect_lsalookupprivilegedisplayname_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_UNICODE_STRING *name */
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
@@ -3428,7 +3443,7 @@ lsa_dissect_lsastoreprivatedata_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_UNICODE_STRING *key */
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
@@ -3459,7 +3474,7 @@ lsa_dissect_lsaretrieveprivatedata_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] LSA_UNICODE_STRING *key */
        offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
@@ -3496,7 +3511,7 @@ lsa_dissect_lsaclosetrusteddomainex_rqst(tvbuff_t *tvb, int offset,
 
        /* [in, out] LSA_HANDLE *tdHnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -3509,7 +3524,7 @@ lsa_dissect_lsaclosetrusteddomainex_reply(tvbuff_t *tvb, int offset,
 
        /* [in, out] LSA_HANDLE *tdHnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -3581,7 +3596,7 @@ lsa_dissect_lsalookupsids2_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
@@ -3679,7 +3694,7 @@ lsa_dissect_lsacreatetrusteddomainex_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] TRUSTED_DOMAIN_INFORMATION_EX *info */
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -3705,7 +3720,7 @@ lsa_dissect_lsacreatetrusteddomainex_reply(tvbuff_t *tvb, int offset,
 {
        /* [out] LSA_HANDLE *tdHnd) */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
@@ -3719,7 +3734,7 @@ lsa_dissect_lsaenumeratetrusteddomainsex_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, out, ref] LSA_ENUMERATION_HANDLE *resume_hnd */
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
@@ -3789,7 +3804,7 @@ lsa_dissect_lsafunction_38_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE handle */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in] USHORT flag */
        offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
@@ -3825,7 +3840,7 @@ lsa_dissect_lsafunction_3b_rqst(tvbuff_t *tvb, int offset,
 {
        /* [in] LSA_HANDLE hnd */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        /* [in, ref] TRUSTED_DOMAIN_INFORMATION_EX *info */
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
@@ -3851,7 +3866,7 @@ lsa_dissect_lsafunction_3b_reply(tvbuff_t *tvb, int offset,
 {
        /* [out] LSA_HANDLE *h2) */
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                       hf_lsa_hnd, NULL, FALSE, FALSE);
+                       hf_lsa_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_lsa_rc, NULL);
index 75e86fe3aed53fdf3106cc622cd20152be8e64b0..834ec209a337204407885906fbf73d60b2e0fb5c 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for MS Exchange MAPI
  * Copyright 2002, Ronnie Sahlberg
  *
- * $Id: packet-dcerpc-mapi.c,v 1.21 2003/05/10 02:15:04 guy Exp $
+ * $Id: packet-dcerpc-mapi.c,v 1.22 2003/06/05 04:22:03 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -253,7 +253,7 @@ mapi_logon_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_mapi_hnd, NULL, FALSE, FALSE);
+                                      hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
 
         DISSECT_UNKNOWN(20); /* this is 20 bytes, unless there are pointers */
 
@@ -283,7 +283,7 @@ mapi_unknown_02_request(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_mapi_hnd, NULL, FALSE, FALSE);
+                                      hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
 
        if(!mapi_decrypt){
                /* this is a unidimensional varying and conformant array of
@@ -309,7 +309,7 @@ mapi_unknown_02_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_mapi_hnd, NULL, FALSE, FALSE);
+                                      hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
 
        if(!mapi_decrypt){
                /* this is a unidimensional varying and conformant array of
@@ -336,7 +336,7 @@ mapi_logoff_rqst(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_mapi_hnd, NULL, FALSE, FALSE);
+                                      hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -346,7 +346,7 @@ mapi_logoff_reply(tvbuff_t *tvb, int offset,
        packet_info *pinfo, proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_mapi_hnd, NULL, FALSE, FALSE);
+                                      hf_mapi_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
                        hf_mapi_rc, NULL);
index 930c28841955db4c2dab512c03aabf01e85b0edd..d62dc49ad7300ac6765a21ab7d5fc4a2b9edde6a 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for DCERPC over SMB packet disassembly
  * Copyright 2001-2003, Tim Potter <tpot@samba.org>
  *
- * $Id: packet-dcerpc-nt.c,v 1.74 2003/05/15 05:24:18 guy Exp $
+ * $Id: packet-dcerpc-nt.c,v 1.75 2003/06/05 04:22:03 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -247,22 +247,53 @@ dissect_ndr_nt_NTTIME (tvbuff_t *tvb, int offset,
 #undef DEBUG_HASH_COLL
 
 /*
- * Policy handle hashing
+ * Policy handle hashing.
+ *
+ * We hash based on the policy handle value; the items in the hash table
+ * are lists of policy handle information about one or more policy
+ * handles with that value.  We have multiple values in case a given
+ * policy handle is opened in frame N, closed in frame M, and re-opened
+ * in frame O, where N < M < O.
+ *
+ * XXX - we really should also use a DCE RPC conversation/session handle
+ * of some sort, in case two separate sessions have the same handle
+ * value.  A transport-layer conversation might not be sufficient, as you
+ * might, for example, have multiple pipes in a single SMB connection,
+ * and you might have the same handle opened and closed separately on
+ * those two pipes.
+ *
+ * The policy handle information has "first frame" and "last frame"
+ * information; the entry should be used when dissecting a given frame
+ * only if that frame is within the interval [first frame,last frame].
+ * The list is sorted by "first frame".
+ *
+ * This doesn't handle the case of a handle being opened in frame N and
+ * re-opened in frame M, where N < M, with no intervening close, but I'm
+ * not sure anything can handle that if it's within the same DCE RPC
+ * session (if it's not, the conversation/session handle would fix that).
  */
 
 typedef struct {
        guint8 policy_hnd[20];
 } pol_hash_key;
 
-typedef struct {
+typedef struct pol_value {
+       struct pol_value *next;          /* Next entry in hash bucket */
        guint32 open_frame, close_frame; /* Frame numbers for open/close */
+       guint32 first_frame;             /* First frame in which this instance was seen */
+       guint32 last_frame;              /* Last frame in which this instance was seen */
        char *name;                      /* Name of policy handle */
+} pol_value;
+
+typedef struct {
+       pol_value *list;                 /* List of policy handle entries */
 } pol_hash_value;
 
 #define POL_HASH_INIT_COUNT 100
 
 static GHashTable *pol_hash;
 static GMemChunk *pol_hash_key_chunk;
+static GMemChunk *pol_value_chunk;
 static GMemChunk *pol_hash_value_chunk;
 
 /* Hash function */
@@ -298,113 +329,248 @@ static gint pol_hash_compare(gconstpointer k1, gconstpointer k2)
                      sizeof(key1->policy_hnd)) == 0;
 }
 
-/* Store the open and close frame numbers of a policy handle */
-
-void dcerpc_smb_store_pol_pkts(e_ctx_hnd *policy_hnd, guint32 open_frame,
-                              guint32 close_frame)
+/*
+ * Look up the instance of a policy handle value in whose range of frames
+ * the specified frame falls.
+ */
+static pol_value *find_pol_handle(e_ctx_hnd *policy_hnd, guint32 frame,
+                                 pol_hash_value **valuep)
 {
-       pol_hash_key *key;
-       pol_hash_value *value;
-
-       if (is_null_pol(policy_hnd) || (open_frame == 0 && close_frame == 0))
-               return;
+       pol_hash_key key;
+       pol_value *pol;
 
-       /* Look up existing value */
+       memcpy(&key.policy_hnd, policy_hnd, sizeof(key.policy_hnd));
+       if ((*valuep = g_hash_table_lookup(pol_hash, &key))) {
+               /*
+                * Look for the first value such that both:
+                *
+                *      1) the first frame in which it was seen is
+                *         <= the specified frame;
+                *
+                *      2) the last frame in which it was seen is
+                *         either unknown (meaning we haven't yet
+                *         seen a close or another open of the
+                *         same handle, which is assumed to imply
+                *         an intervening close that wasn't captured)
+                *         or is >= the specified frame.
+                *
+                * If there's more than one such frame, that's the
+                * case where a handle is opened in frame N and
+                * reopened in frame M, with no intervening close;
+                * there is no right answer for that, so the instance
+                * opened in frame N is as right as anything else.
+                */
+               for (pol = (*valuep)->list; pol != NULL; pol = pol->next) {
+                       if (pol->first_frame <= frame &&
+                           (pol->last_frame == 0 ||
+                            pol->last_frame >= frame))
+                               break;  /* found one */
+               }
+               return pol;
+       } else {
+               /*
+                * The handle isn't in the hash table.
+                */
+               return NULL;
+       }
+}
 
-       key = g_mem_chunk_alloc(pol_hash_key_chunk);
+static void add_pol_handle(e_ctx_hnd *policy_hnd, guint32 frame,
+                          pol_value *pol, pol_hash_value *value)
+{
+       pol_hash_key *key;
+       pol_value *polprev, *polnext;
+
+       if (value == NULL) {
+               /*
+                * There's no hash value; create one, put the new
+                * value at the beginning of its policy handle list,
+                * and put the hash value in the policy handle hash
+                * table.
+                */
+               value = g_mem_chunk_alloc(pol_hash_value_chunk);
+               value->list = pol;
+               pol->next = NULL;
+               key = g_mem_chunk_alloc(pol_hash_key_chunk);
+               memcpy(&key->policy_hnd, policy_hnd, sizeof(key->policy_hnd));
+               g_hash_table_insert(pol_hash, key, value);
+       } else {
+               /*
+                * Put the new value in the hash value's policy handle
+                * list so that it's sorted by the first frame in
+                * which it appeared.
+                *
+                * Search for the first entry whose first frame number
+                * is greater than the current frame number, if any.
+                */
+               for (polnext = value->list, polprev = NULL;
+                   polnext != NULL && polnext->first_frame <= frame;
+                   polprev = polnext, polnext = polnext->next)
+                       ;
+
+               /*
+                * "polprev" points to the entry in the list after
+                * which we should put the new entry; if it's null,
+                * that means we should put it at the beginning of
+                * the list.
+                */
+               if (polprev == NULL)
+                       value->list = pol;
+               else
+                       polprev->next = pol;
+               
+               /*
+                * "polnext" points to the entry in the list before
+                * which we should put the new entry; if it's null,
+                * that means we should put it at the end of the list.
+                */
+               pol->next = polnext;
+       }
+}
 
-       memcpy(&key->policy_hnd, policy_hnd, sizeof(key->policy_hnd));
+/* Store the open and close frame numbers of a policy handle */
 
-       if ((value = g_hash_table_lookup(pol_hash, key))) {
+void dcerpc_smb_store_pol_pkts(e_ctx_hnd *policy_hnd, packet_info *pinfo,
+                              gboolean is_open, gboolean is_close)
+{
+       pol_hash_value *value;
+       pol_value *pol;
 
-               /* Update existing value */
+       /*
+        * By the time the first pass is done, the policy handle database
+        * has been completely constructed.  If we've already seen this
+        * frame, there's nothing to do.
+        */
+       if (pinfo->fd->flags.visited)
+               return;
 
-               if (open_frame) {
-#ifdef DEBUG_HASH_COLL
-                       if (value->open_frame != open_frame)
-                               g_warning("dcerpc_smb: pol_hash open frame collision %d/%d\n", value->open_frame, open_frame);
-#endif
-                       value->open_frame = open_frame;
-               }
+       if (is_null_pol(policy_hnd))
+               return;
 
-               if (close_frame) {
-#ifdef DEBUG_HASH_COLL
-                       if (value->close_frame != close_frame)
-                               g_warning("dcerpc_smb: pol_hash close frame collision %d/%d\n", value->close_frame, close_frame);
-#endif
-                       value->close_frame = close_frame;
+       /* Look up existing value */
+       pol = find_pol_handle(policy_hnd, pinfo->fd->num, &value);
+
+       if (pol != NULL) {
+               /*
+                * Update the existing value as appropriate.
+                */
+               if (is_open) {
+                       /*
+                        * This is an open; we assume that we missed
+                        * a close of this handle, so we set its
+                        * "last frame" value and act as if we didn't
+                        * see it.
+                        *
+                        * XXX - note that we might be called twice for
+                        * the same operation (see "dissect_pipe_dcerpc()",
+                        * which calls the DCE RPC dissector twice), so we
+                        * must first check to see if this is a handle we
+                        * just filled in.
+                        *
+                        * We check whether this handle's "first frame"
+                        * frame number is this frame and its "last frame
+                        * is 0; if so, this is presumably a duplicate call,
+                        * and we don't do an implicit close.
+                        */
+                       if (pol->first_frame == pinfo->fd->num &&
+                           pol->last_frame == 0)
+                               return;
+                       pol->last_frame = pinfo->fd->num;
+                       pol = NULL;
+               } else {
+                       if (is_close) {
+                               pol->close_frame = pinfo->fd->num;
+                               pol->last_frame = pinfo->fd->num;
+                       }
+                       return;
                }
-
-               return;
        }
 
        /* Create a new value */
 
-       value = g_mem_chunk_alloc(pol_hash_value_chunk);
+       pol = g_mem_chunk_alloc(pol_value_chunk);
 
-       value->open_frame = open_frame;
-       value->close_frame = close_frame;
+       pol->open_frame = is_open ? pinfo->fd->num : 0;
+       pol->close_frame = is_close ? pinfo->fd->num : 0;
+       pol->first_frame = pinfo->fd->num;
+       pol->last_frame = pol->close_frame;     /* if 0, unknown; if non-0, known */
 
-       value->name = NULL;
+       pol->name = NULL;
 
-       g_hash_table_insert(pol_hash, key, value);
+       add_pol_handle(policy_hnd, pinfo->fd->num, pol, value);
 }
 
 /* Store a text string with a policy handle */
 
-void dcerpc_smb_store_pol_name(e_ctx_hnd *policy_hnd, char *name)
+void dcerpc_smb_store_pol_name(e_ctx_hnd *policy_hnd, packet_info *pinfo,
+                              char *name)
 {
-       pol_hash_key *key;
        pol_hash_value *value;
+       pol_value *pol;
+
+       /*
+        * By the time the first pass is done, the policy handle database
+        * has been completely constructed.  If we've already seen this
+        * frame, there's nothing to do.
+        */
+       if (pinfo->fd->flags.visited)
+               return;
 
        if (is_null_pol(policy_hnd))
                return;
 
        /* Look up existing value */
-
-       key = g_mem_chunk_alloc(pol_hash_key_chunk);
-
-       memcpy(&key->policy_hnd, policy_hnd, sizeof(key->policy_hnd));
-
-       if ((value = g_hash_table_lookup(pol_hash, key))) {
-
-               /* Update existing value */
-
-               if (value->name && name) {
+       pol = find_pol_handle(policy_hnd, pinfo->fd->num, &value);
+
+       if (pol != NULL) {
+               /*
+                * This is the first pass; update the existing
+                * value as appropriate.
+                */
+               if (pol->name && name) {
 #ifdef DEBUG_HASH_COLL
-                       if (strcmp(value->name, name) != 0)
+                       if (strcmp(pol->name, name) != 0)
                                g_warning("dcerpc_smb: pol_hash name collision %s/%s\n", value->name, name);
 #endif
-                       free(value->name);
+                       free(pol->name);
                }
 
-               value->name = strdup(name);
+               pol->name = strdup(name);
 
                return;
        }
 
        /* Create a new value */
 
-       value = g_mem_chunk_alloc(pol_hash_value_chunk);
+       pol = g_mem_chunk_alloc(pol_value_chunk);
 
-       value->open_frame = 0;
-       value->close_frame = 0;
+       pol->open_frame = 0;
+       pol->close_frame = 0;
+       pol->first_frame = pinfo->fd->num;
+       pol->last_frame = 0;
 
        if (name)
-               value->name = strdup(name);
+               pol->name = strdup(name);
        else
-               value->name = strdup("<UNKNOWN>");
+               pol->name = strdup("<UNKNOWN>");
 
-       g_hash_table_insert(pol_hash, key, value);
+       add_pol_handle(policy_hnd, pinfo->fd->num, pol, value);
 }
 
-/* Retrieve a policy handle */
+/*
+ * Retrieve a policy handle.
+ *
+ * XXX - should this get an "is_close" argument, and match even closed
+ * policy handles if the call is a close, so we can handle retransmitted
+ * close operations?
+ */
 
 gboolean dcerpc_smb_fetch_pol(e_ctx_hnd *policy_hnd, char **name,
-                             guint32 *open_frame, guint32 *close_frame)
+                             guint32 *open_frame, guint32 *close_frame,
+                             guint32 cur_frame)
 {
-       pol_hash_key key;
        pol_hash_value *value;
+       pol_value *pol;
 
        /* Prevent uninitialised return vars */
 
@@ -418,39 +584,37 @@ gboolean dcerpc_smb_fetch_pol(e_ctx_hnd *policy_hnd, char **name,
                *close_frame = 0;
 
        /* Look up existing value */
+       pol = find_pol_handle(policy_hnd, cur_frame, &value);
 
-       memcpy(&key.policy_hnd, policy_hnd, sizeof(key.policy_hnd));
-
-       value = g_hash_table_lookup(pol_hash, &key);
-
-       /* Return name and frame numbers */
-
-       if (value) {
+       if (pol) {
                if (name)
-                       *name = value->name;
+                       *name = pol->name;
 
                if (open_frame)
-                       *open_frame = value->open_frame;
+                       *open_frame = pol->open_frame;
 
                if (close_frame)
-                       *close_frame = value->close_frame;
+                       *close_frame = pol->close_frame;
        }
 
-       return value != NULL;
+       return pol != NULL;
 }
 
-/* Iterator to free a policy handle key/value pair */
+/* Iterator to free a policy handle key/value pair, and all
+   the policy handle values to which the hash table value
+   points */
 
-static void free_pol_keyvalue(gpointer key _U_, gpointer value,
+static void free_pol_keyvalue(gpointer key _U_, gpointer value_arg,
     gpointer user_data _U_)
 {
-       pol_hash_value *pol_value = (pol_hash_value *)value;
+       pol_hash_value *value = (pol_hash_value *)value_arg;
+       pol_value *pol;
 
        /* Free user data */
 
-       if (pol_value->name) {
-               free(pol_value->name);
-               pol_value->name = NULL;
+       for (pol = value->list; pol != NULL; pol = pol->next) {
+               free(pol->name);
+               pol->name = NULL;
        }
 }
 
@@ -467,6 +631,13 @@ static void init_pol_hash(void)
                "Policy handle hash keys", sizeof(pol_hash_key),
                POL_HASH_INIT_COUNT * sizeof(pol_hash_key), G_ALLOC_ONLY);
 
+       if (pol_value_chunk)
+               g_mem_chunk_destroy(pol_value_chunk);
+
+       pol_value_chunk = g_mem_chunk_new(
+               "Policy handle values", sizeof(pol_value),
+               POL_HASH_INIT_COUNT * sizeof(pol_value), G_ALLOC_ONLY);
+
        if (pol_hash_value_chunk)
                g_mem_chunk_destroy(pol_hash_value_chunk);
 
@@ -560,7 +731,8 @@ static gint ett_nt_policy_hnd = -1;
 int
 dissect_nt_policy_hnd(tvbuff_t *tvb, gint offset, packet_info *pinfo,
                      proto_tree *tree, char *drep, int hfindex,
-                     e_ctx_hnd *pdata, gboolean is_open, gboolean is_close)
+                     e_ctx_hnd *pdata, proto_item **pitem,
+                     gboolean is_open, gboolean is_close)
 {
        proto_item *item;
        proto_tree *subtree;
@@ -568,6 +740,18 @@ dissect_nt_policy_hnd(tvbuff_t *tvb, gint offset, packet_info *pinfo,
        guint32 open_frame = 0, close_frame = 0;
        char *name;
        int old_offset = offset;
+       dcerpc_info *di;
+
+       di=pinfo->private_data;
+       if(di->conformant_run){
+               /*
+                * just a run to handle conformant arrays, no scalars to
+                * dissect - and "dissect_ndr_ctx_hnd()" won't return
+                * a handle, so we can't do the hashing stuff in any
+                * case
+                */
+               return offset;
+       }
 
        /* Add to proto tree */
 
@@ -579,14 +763,17 @@ dissect_nt_policy_hnd(tvbuff_t *tvb, gint offset, packet_info *pinfo,
        offset = dissect_ndr_ctx_hnd(tvb, offset, pinfo, subtree, drep,
                                     hfindex, &hnd);
 
-       /* Store request/reply information */
-
-       dcerpc_smb_store_pol_pkts(&hnd, 0, is_close ? pinfo->fd->num : 0);
-       dcerpc_smb_store_pol_pkts(&hnd, is_open ? pinfo->fd->num: 0, 0);
+       /*
+        * Create a new entry for this handle if it's not a null handle
+        * and no entry already exists, and, in any case, set the
+        * open, close, first, and last frame information as appropriate.
+        */
+       dcerpc_smb_store_pol_pkts(&hnd, pinfo, is_open, is_close);
 
-       /* Insert request/reply information if known */
+       /* Insert open/close/name information if known */
 
-       if (dcerpc_smb_fetch_pol(&hnd, &name, &open_frame, &close_frame)) {
+       if (dcerpc_smb_fetch_pol(&hnd, &name, &open_frame, &close_frame,
+           pinfo->fd->num)) {
 
                if (open_frame)
                        proto_tree_add_uint(
@@ -598,13 +785,22 @@ dissect_nt_policy_hnd(tvbuff_t *tvb, gint offset, packet_info *pinfo,
                                subtree, hf_nt_policy_close_frame, tvb,
                                old_offset, sizeof(e_ctx_hnd), close_frame);
 
-               if (name != NULL)
+               /*
+                * Don't append the handle name if pitem is null; that's
+                * an indication that our caller will do so, as we're
+                * supplying a pointer to the item so that they can do
+                * so.
+                */
+               if (name != NULL && pitem == NULL)
                        proto_item_append_text(item, ": %s", name);
        }
 
        if (pdata)
                *pdata = hnd;
 
+       if (pitem)
+               *pitem = item;
+
        return offset;
 }
 
index 01700a6b9ebba70a8aca15f485d394deab3008e9..68a3b1e6a4a8916f5ca460a86034c6f4c82bdcf1 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for DCERPC over SMB packet disassembly
  * Copyright 2001-2003 Tim Potter <tpot@samba.org>
  *
- * $Id: packet-dcerpc-nt.h,v 1.46 2003/05/21 10:06:29 sahlberg Exp $
+ * $Id: packet-dcerpc-nt.h,v 1.47 2003/06/05 04:22:03 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -117,19 +117,21 @@ dissect_ndr_nt_SID_AND_ATTRIBUTES(tvbuff_t *tvb, int offset,
 /* Store open and close packet numbers for a policy handle */
 
 void
-dcerpc_smb_store_pol_pkts(e_ctx_hnd *policy_hnd, guint32 open_frame,
-                         guint32 close_frame);
+dcerpc_smb_store_pol_pkts(e_ctx_hnd *policy_hnd, packet_info *pinfo,
+                         gboolean is_open, gboolean is_close);
 
 /* Store a name with a policy handle */
 
 void
-dcerpc_smb_store_pol_name(e_ctx_hnd *policy_hnd, char *name);
+dcerpc_smb_store_pol_name(e_ctx_hnd *policy_hnd, packet_info *pinfo,
+                         char *name);
 
 /* Fetch details stored with a policy handle */
 
 gboolean
 dcerpc_smb_fetch_pol(e_ctx_hnd *policy_hnd, char **name,
-                    guint32 *open_frame, guint32 *close_frame);
+                    guint32 *open_frame, guint32 *close_frame,
+                    guint32 cur_frame);
 
 /* Check for unparsed data at the end of a frame */
 
@@ -152,7 +154,8 @@ dissect_doserror(tvbuff_t *tvb, gint offset, packet_info *pinfo,
 int
 dissect_nt_policy_hnd(tvbuff_t *tvb, gint offset, packet_info *pinfo,
                      proto_tree *tree, char *drep, int hfindex,
-                     e_ctx_hnd *pdata, gboolean is_open, gboolean is_close);
+                     e_ctx_hnd *pdata, proto_item **pitem,
+                     gboolean is_open, gboolean is_close);
 
 int
 dissect_nt_GUID(tvbuff_t *tvb, int offset,
index 4642fb7c2d3d8179ba215c10362d479f9ba67175..55b1cbc9685f8ce707987415cdd582c5df1a2484 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for SMB \PIPE\winreg packet disassembly
  * Copyright 2001-2003 Tim Potter <tpot@samba.org>
  *
- * $Id: packet-dcerpc-reg.c,v 1.16 2003/04/21 01:13:41 guy Exp $
+ * $Id: packet-dcerpc-reg.c,v 1.17 2003/06/05 04:22:03 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -112,17 +112,23 @@ RegOpenHKLM_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
              proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, &policy_hnd, TRUE, FALSE);
-
-       dcerpc_smb_store_pol_name(&policy_hnd, "HKLM handle");
+               hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_rc, NULL);
+                                 hf_rc, &status);
+
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKLM handle");
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": HKLM handle");
+       }
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -154,17 +160,23 @@ RegOpenHKU_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
             proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, &policy_hnd, TRUE, FALSE);
-
-       dcerpc_smb_store_pol_name(&policy_hnd, "HKU handle");
+               hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(
-               tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+               tvb, offset, pinfo, tree, drep, hf_rc, &status);
+
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKU handle");
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": HKU handle");
+       }
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -196,17 +208,23 @@ RegOpenHKCR_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
              proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, &policy_hnd, TRUE, FALSE);
-
-       dcerpc_smb_store_pol_name(&policy_hnd, "HKCR handle");
+               hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(
-               tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+               tvb, offset, pinfo, tree, drep, hf_rc, &status);
+
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKCR handle");
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": HKCR handle");
+       }
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -225,7 +243,7 @@ RegClose_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, TRUE);
+               hf_hnd, NULL, NULL, FALSE, TRUE);
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -240,7 +258,7 @@ RegClose_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_rc, NULL);
@@ -262,7 +280,7 @@ RegQueryKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_counted_string(
                tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
@@ -332,7 +350,7 @@ RegOpenEntry_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_counted_string(
                tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
@@ -355,17 +373,24 @@ RegOpenEntry_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
               proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, &policy_hnd, TRUE, FALSE);
-
-       dcerpc_smb_store_pol_name(&policy_hnd, "OpenEntry handle");
+               hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(
-               tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+               tvb, offset, pinfo, tree, drep, hf_rc, &status);
+
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
+                       "OpenEntry handle");
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": OpenEntry handle");
+       }
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -384,7 +409,7 @@ RegUnknown1A_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -421,7 +446,7 @@ RegEnumKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
index 9372471963a8440a69b2a5dcdc3daadaa4e4750c..2244f966c1f30be2b475fc2e0845832622a9ca22 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright 2001,2003 Tim Potter <tpot@samba.org>
  *   2002 Added all command dissectors  Ronnie Sahlberg
  *
- * $Id: packet-dcerpc-samr.c,v 1.94 2003/05/30 23:44:13 sahlberg Exp $
+ * $Id: packet-dcerpc-samr.c,v 1.95 2003/06/05 04:22:03 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -622,7 +622,7 @@ samr_dissect_open_user_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo,
        guint32 rid;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                        hf_samr_access, NULL);
@@ -646,23 +646,31 @@ samr_dissect_open_user_reply(tvbuff_t *tvb, int offset,
        dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
        guint32 rid = GPOINTER_TO_INT(dcv->private_data);
        char *pol_name;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
 
-       if (rid)
-               pol_name = g_strdup_printf("OpenUser(rid 0x%x)", rid);
-       else
-               pol_name = g_strdup("OpenUser handle");
+       offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+                                 hf_samr_rc, &status);
 
-       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+       if (status == 0) {
+               if (rid)
+                       pol_name = g_strdup_printf("OpenUser(rid 0x%x)", rid);
+               else
+                       pol_name = g_strdup("OpenUser handle");
 
-       g_free(pol_name);
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
 
-       offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_samr_rc, NULL);
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": %s", pol_name);
+
+               g_free(pol_name);
+       }
 
        return offset;
 }
@@ -721,7 +729,7 @@ samr_dissect_query_dispinfo_rqst(tvbuff_t *tvb, int offset,
        guint32 start_idx;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_level, &level);
@@ -1089,7 +1097,7 @@ samr_dissect_get_display_enumeration_index_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_level, &level);
@@ -1154,7 +1162,7 @@ samr_dissect_get_usrdom_pwinfo_rqst(tvbuff_t *tvb, int offset,
                                    char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -1220,22 +1228,31 @@ samr_dissect_connect2_reply(tvbuff_t *tvb, int offset,
        dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
        char *server = (char *)dcv->private_data, *pol_name;
        
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
 
-       if (server)
-               pol_name = g_strdup_printf("Connect2(%s)", server);
-       else
-               pol_name = g_strdup("Connect2 handle");
+        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+                                 hf_samr_rc, &status);
 
-       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+       if (status == 0) {
+               if (server)
+                       pol_name = g_strdup_printf("Connect2(%s)", server);
+               else
+                       pol_name = g_strdup("Connect2 handle");
 
-       g_free(pol_name);
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
+
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": %s", pol_name);
+
+               g_free(pol_name);
+       }
 
-        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_samr_rc, NULL);
        return offset;
 }
 
@@ -1263,14 +1280,23 @@ samr_dissect_connect_anon_reply(tvbuff_t *tvb, int offset,
                                char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
-
-       dcerpc_smb_store_pol_name(&policy_hnd, "ConnectAnon handle");
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
 
         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_samr_rc, NULL);
+                                 hf_samr_rc, &status);
+
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
+                                         "ConnectAnon handle");
+
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": ConnectAnon handle");
+       }
 
        return offset;
 }
@@ -1353,7 +1379,7 @@ samr_dissect_get_groups_for_user_rqst(tvbuff_t *tvb, int offset,
                                      char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -1392,7 +1418,7 @@ samr_dissect_open_domain_rqst(tvbuff_t *tvb, int offset,
                              char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_nt_access_mask(
                tvb, offset, pinfo, tree, drep, hf_samr_access,
@@ -1413,23 +1439,31 @@ samr_dissect_open_domain_reply(tvbuff_t *tvb, int offset,
        dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
        char *pol_name, *sid_str = (char *)dcv->private_data;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
 
-       if (sid_str) {
-               pol_name = g_strdup_printf("OpenDomain(%s)", sid_str);
-       } else {
-               pol_name = g_strdup("OpenDomain handle");
-       }
+        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+                                 hf_samr_rc, &status);
 
-       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+       if (status == 0) {
+               if (sid_str) {
+                       pol_name = g_strdup_printf("OpenDomain(%s)", sid_str);
+               } else {
+                       pol_name = g_strdup("OpenDomain handle");
+               }
 
-       g_free(pol_name);
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
 
-        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_samr_rc, NULL);
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": %s", pol_name);
+
+               g_free(pol_name);
+       }
 
        return offset;
 }
@@ -1441,7 +1475,7 @@ samr_dissect_context_handle_SID(tvbuff_t *tvb, int offset,
                              char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_SID_no_hf, NDR_POINTER_REF,
@@ -1457,7 +1491,7 @@ samr_dissect_add_member_to_group_rqst(tvbuff_t *tvb, int offset,
                                      char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_group, NULL);
@@ -1485,7 +1519,7 @@ samr_dissect_unknown_3c_rqst(tvbuff_t *tvb, int offset,
                             char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -1510,7 +1544,7 @@ samr_dissect_create_alias_in_domain_rqst(tvbuff_t *tvb, int offset,
                                         char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
@@ -1529,18 +1563,26 @@ samr_dissect_create_alias_in_domain_reply(tvbuff_t *tvb, int offset,
                              char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
-
-       dcerpc_smb_store_pol_name(&policy_hnd, "CreateAlias handle");
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
 
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_rid, NULL);
 
         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_samr_rc, NULL);
+                                 hf_samr_rc, &status);
+
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
+                                         "CreateAlias handle");
 
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": CreateAlias handle");
+       }
        return offset;
 }
 
@@ -1552,7 +1594,7 @@ samr_dissect_query_information_alias_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                        hf_samr_level, &level);
@@ -1648,7 +1690,7 @@ samr_dissect_set_information_alias_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_level, &level);
@@ -1938,7 +1980,7 @@ samr_dissect_oem_change_password_user2_rqst(tvbuff_t *tvb, int offset,
                                            proto_tree *tree, char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        samr_dissect_pointer_STRING, NDR_POINTER_UNIQUE,
@@ -2019,7 +2061,7 @@ samr_dissect_unknown_3b_rqst(tvbuff_t *tvb, int offset,
                              char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_unknown_short, NULL);
@@ -2049,7 +2091,7 @@ samr_dissect_create_user2_in_domain_rqst(tvbuff_t *tvb, int offset,
                                         char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
@@ -2070,11 +2112,12 @@ samr_dissect_create_user2_in_domain_reply(tvbuff_t *tvb, int offset,
                              char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
-
-       dcerpc_smb_store_pol_name(&policy_hnd, "CreateUser2 handle");
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
 
        offset = dissect_nt_access_mask(
                tvb, offset, pinfo, tree, drep, hf_samr_access_granted,
@@ -2084,7 +2127,16 @@ samr_dissect_create_user2_in_domain_reply(tvbuff_t *tvb, int offset,
                                      hf_samr_rid, NULL);
 
         offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_samr_rc, NULL);
+                                 hf_samr_rc, &status);
+
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
+                                         "CreateUser2 handle");
+
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": CreateUser2 handle");
+       }
+
        return offset;
 }
 
@@ -2094,7 +2146,7 @@ samr_dissect_get_display_enumeration_index2_rqst(tvbuff_t *tvb, int offset,
                                                 proto_tree *tree, char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_level, NULL);
@@ -2123,7 +2175,7 @@ samr_dissect_change_password_user_rqst(tvbuff_t *tvb, int offset,
                                       char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint8 (tvb, offset, pinfo, tree, drep,
                        hf_samr_unknown_char, NULL);
@@ -2172,7 +2224,7 @@ samr_dissect_set_member_attributes_of_group_rqst(tvbuff_t *tvb, int offset,
                                                 proto_tree *tree, char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_attrib, NULL);
@@ -2264,7 +2316,7 @@ samr_dissect_query_information_group_rqst(tvbuff_t *tvb, int offset,
                                          proto_tree *tree, char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_level, NULL);
@@ -2294,7 +2346,7 @@ samr_dissect_set_information_group_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_level, &level);
@@ -2612,7 +2664,7 @@ samr_dissect_set_information_domain_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_level, &level);
@@ -2642,7 +2694,7 @@ samr_dissect_lookup_domain_rqst(tvbuff_t *tvb, int offset,
                                char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
@@ -2865,7 +2917,7 @@ samr_dissect_get_alias_membership_rqst(tvbuff_t *tvb, int offset,
                                       char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
@@ -2993,7 +3045,7 @@ samr_dissect_enum_domains_rqst(tvbuff_t *tvb, int offset,
                               char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        samr_dissect_pointer_long, NDR_POINTER_REF,
@@ -3034,7 +3086,7 @@ samr_dissect_enum_dom_groups_rqst(tvbuff_t *tvb, int offset,
                                  char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        samr_dissect_pointer_long, NDR_POINTER_REF,
@@ -3078,7 +3130,7 @@ samr_dissect_enum_dom_aliases_rqst(tvbuff_t *tvb, int offset,
                                 char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        samr_dissect_pointer_long, NDR_POINTER_REF,
@@ -3122,7 +3174,7 @@ samr_dissect_get_members_in_alias_rqst(tvbuff_t *tvb, int offset,
                                       char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -3801,7 +3853,7 @@ samr_dissect_set_information_user2_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                        hf_samr_level, &level);
@@ -3835,7 +3887,7 @@ samr_dissect_unknown_2f_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                        hf_samr_level, &level);
@@ -3979,7 +4031,7 @@ samr_dissect_query_groupmem_rqst(tvbuff_t *tvb, int offset,
                                 char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         return offset;
 }
@@ -4007,7 +4059,7 @@ samr_dissect_set_sec_object_rqst(tvbuff_t *tvb, int offset,
        guint32 info_type;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                        hf_samr_info_type, &info_type);
@@ -4042,7 +4094,7 @@ samr_dissect_query_sec_object_rqst(tvbuff_t *tvb, int offset,
        guint32 info_type;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                        hf_samr_info_type, &info_type);
@@ -4108,7 +4160,7 @@ samr_dissect_lookup_names_rqst(tvbuff_t *tvb, int offset,
                               char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                        hf_samr_count, NULL);
@@ -4179,7 +4231,7 @@ samr_dissect_lookup_rids_rqst(tvbuff_t *tvb, int offset,
                              char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
                        hf_samr_count, NULL);
@@ -4268,9 +4320,9 @@ samr_dissect_close_hnd_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
         offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_samr_hnd, &policy_hnd, 
-               FALSE, TRUE);
+               NULL, FALSE, TRUE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &name, NULL, NULL, pinfo->fd->num);
 
        if (name != NULL && check_col(pinfo->cinfo, COL_INFO))
                col_append_fstr(
@@ -4284,7 +4336,7 @@ samr_dissect_close_hnd_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
                             proto_tree *tree, char *drep)
 {
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
                        hf_samr_rc, NULL);
@@ -4298,7 +4350,7 @@ samr_dissect_shutdown_sam_server_rqst(tvbuff_t *tvb, int offset,
                                      char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         return offset;
 }
@@ -4320,7 +4372,7 @@ samr_dissect_delete_dom_group_rqst(tvbuff_t *tvb, int offset,
                                   char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         return offset;
 }
@@ -4342,7 +4394,7 @@ samr_dissect_remove_member_from_group_rqst(tvbuff_t *tvb, int offset,
                                           proto_tree *tree, char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_group, NULL);
@@ -4370,7 +4422,7 @@ samr_dissect_delete_dom_alias_rqst(tvbuff_t *tvb, int offset,
                                   char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         return offset;
 }
@@ -4392,7 +4444,7 @@ samr_dissect_add_alias_member_rqst(tvbuff_t *tvb, int offset,
                                   char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_SID_no_hf, NDR_POINTER_REF,
@@ -4418,7 +4470,7 @@ samr_dissect_remove_alias_member_rqst(tvbuff_t *tvb, int offset,
                                      char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_SID_no_hf, NDR_POINTER_REF,
@@ -4444,7 +4496,7 @@ samr_dissect_delete_dom_user_rqst(tvbuff_t *tvb, int offset,
                                  char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -4466,7 +4518,7 @@ samr_dissect_test_private_fns_domain_rqst(tvbuff_t *tvb, int offset,
                                          char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -4488,7 +4540,7 @@ samr_dissect_test_private_fns_user_rqst(tvbuff_t *tvb, int offset,
                                        char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -4511,7 +4563,7 @@ samr_dissect_remove_member_from_foreign_domain_rqst(tvbuff_t *tvb, int offset,
                                                    char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_SID_no_hf, NDR_POINTER_REF,
@@ -4540,7 +4592,7 @@ samr_dissect_remove_multiple_members_from_alias_rqst(tvbuff_t *tvb,
                                                     char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
@@ -4571,7 +4623,7 @@ samr_dissect_open_group_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo,
        guint32 rid;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_nt_access_mask(
                tvb, offset, pinfo, tree, drep, hf_samr_access,
@@ -4597,22 +4649,30 @@ samr_dissect_open_group_reply(tvbuff_t *tvb, int offset,
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        guint32 rid = GPOINTER_TO_INT(dcv->private_data);
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
        char *pol_name;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
 
-       if (rid)
-               pol_name = g_strdup_printf("OpenGroup(rid 0x%x)", rid);
-       else
-               pol_name = g_strdup("OpenGroup handle");
+       offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+                       hf_samr_rc, &status);
 
-       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+       if (status == 0) {
+               if (rid)
+                       pol_name = g_strdup_printf("OpenGroup(rid 0x%x)", rid);
+               else
+                       pol_name = g_strdup("OpenGroup handle");
 
-       g_free(pol_name);
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
 
-       offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                       hf_samr_rc, NULL);
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": %s", pol_name);
+
+               g_free(pol_name);
+       }
 
        return offset;
 }
@@ -4626,7 +4686,7 @@ samr_dissect_open_alias_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo,
        guint32 rid;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_nt_access_mask(
                tvb, offset, pinfo, tree, drep, hf_samr_access,
@@ -4652,24 +4712,32 @@ samr_dissect_open_alias_reply(tvbuff_t *tvb, int offset,
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
        char *pol_name;
+       proto_item *hnd_item;
+       guint32 status;
        guint32 rid;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
+
+       offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+                       hf_samr_rc, &status);
 
-       rid = GPOINTER_TO_INT(dcv->private_data);
+       if (status == 0) {
+               rid = GPOINTER_TO_INT(dcv->private_data);
 
-       if (rid)
-               pol_name = g_strdup_printf("OpenAlias(rid 0x%x)", rid);
-       else
-               pol_name = g_strdup_printf("OpenAlias handle");
+               if (rid)
+                       pol_name = g_strdup_printf("OpenAlias(rid 0x%x)", rid);
+               else
+                       pol_name = g_strdup_printf("OpenAlias handle");
 
-       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
 
-       g_free(pol_name);
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": %s", pol_name);
 
-       offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                       hf_samr_rc, NULL);
+               g_free(pol_name);
+       }
 
        return offset;
 }
@@ -4680,7 +4748,7 @@ samr_dissect_add_multiple_members_to_alias_rqst(tvbuff_t *tvb, int offset,
                                                proto_tree *tree, char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_nt_PSID_ARRAY, NDR_POINTER_REF,
@@ -4706,7 +4774,7 @@ samr_dissect_create_group_in_domain_rqst(tvbuff_t *tvb, int offset,
                                         char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
         offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
                        dissect_ndr_counted_string_ptr, NDR_POINTER_REF,
@@ -4725,23 +4793,31 @@ samr_dissect_create_group_in_domain_reply(tvbuff_t *tvb, int offset,
                                          char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
        guint32 rid;
+       guint32 status;
        char *pol_name;
 
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, &policy_hnd, TRUE, FALSE);
+                                      hf_samr_hnd, &policy_hnd, &hnd_item,
+                                      TRUE, FALSE);
 
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                                      hf_samr_rid, &rid);
 
-       pol_name = g_strdup_printf("CreateGroup(rid 0x%x)", rid);
+        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+                                 hf_samr_rc, &status);
 
-       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+       if (status == 0) {
+               pol_name = g_strdup_printf("CreateGroup(rid 0x%x)", rid);
 
-       g_free(pol_name);
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
 
-        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_samr_rc, NULL);
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": %s", pol_name);
+
+               g_free(pol_name);
+       }
 
        return offset;
 }
@@ -4754,7 +4830,7 @@ samr_dissect_query_information_domain_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                        hf_samr_level, &level);
@@ -4792,7 +4868,7 @@ samr_dissect_query_information_user_rqst(tvbuff_t *tvb, int offset,
        guint16 level;
 
        offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_samr_hnd, NULL, FALSE, FALSE);
+                                      hf_samr_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint16 (tvb, offset, pinfo, tree, drep,
                        hf_samr_level, &level);
index 9c1192cb06186b500702b1fec6ba08b162a9fd9d..1e149d0fce21cfedf6a9e05cbbb198c4b2f098f8 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for SMB \PIPE\spoolss packet disassembly
  * Copyright 2001-2003, Tim Potter <tpot@samba.org>
  *
- * $Id: packet-dcerpc-spoolss.c,v 1.99 2003/05/27 07:18:47 guy Exp $
+ * $Id: packet-dcerpc-spoolss.c,v 1.100 2003/06/05 04:22:04 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -544,10 +544,11 @@ static int SpoolssClosePrinter_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, NULL,
                FALSE, TRUE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL,
+                            pinfo->fd->num);
 
        if (check_col(pinfo->cinfo, COL_INFO) && pol_name)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
@@ -565,7 +566,8 @@ static int SpoolssClosePrinter_r(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, FALSE, FALSE);
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
+               FALSE, FALSE);
 
 
        offset = dissect_doserror(
@@ -674,7 +676,7 @@ static int SpoolssGetPrinterData_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        value_name = dcv->private_data;
@@ -750,7 +752,7 @@ static int SpoolssGetPrinterDataEx_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
@@ -852,7 +854,7 @@ static int SpoolssSetPrinterData_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
@@ -916,7 +918,7 @@ static int SpoolssSetPrinterDataEx_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
@@ -2555,19 +2557,17 @@ static int SpoolssOpenPrinterEx_r(tvbuff_t *tvb, int offset,
        dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
        guint32 status;
-       int start_offset = offset;
 
-       /* We need the value of the policy handle and status before we
-          can retrieve the policy handle name.  Then we can insert
-          the policy handle with the name in the proto tree. */
+       /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, NULL, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, &hnd_item,
                TRUE, FALSE);
 
-       offset = dissect_ndr_uint32(
-               tvb, offset, pinfo, NULL, drep, hf_rc, &status);
+       offset = dissect_doserror(
+               tvb, offset, pinfo, tree, drep, hf_rc, &status);
 
        if (status == 0) {
 
@@ -2580,24 +2580,33 @@ static int SpoolssOpenPrinterEx_r(tvbuff_t *tvb, int offset,
                                "OpenPrinterEx(%s)", 
                                (char *)dcv->private_data);
 
-                       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+                       dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
 
                        g_free(pol_name);
                        g_free(dcv->private_data);
                        dcv->private_data = NULL;
                }
-       }
-
-       /* Parse packet */
 
-       offset = start_offset;
+               /*
+                * If we have a name for the handle, attach it to the item.
+                *
+                * XXX - we can't just do that above, as this may be called
+                * twice (see "dissect_pipe_dcerpc()", which calls the
+                * DCE RPC dissector twice), and in the first call we're
+                * not building a protocol tree (so we don't have an item
+                * to which to attach it) and in the second call
+                * "dcv->private_data" is NULL so we don't construct a
+                * name.
+                */
 
-       offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
-               TRUE, FALSE);
+               if (hnd_item != NULL) {
+                       char *name;
 
-       offset = dissect_doserror(
-               tvb, offset, pinfo, tree, drep, hf_rc, &status);
+                       if (dcerpc_smb_fetch_pol(&policy_hnd, &name, NULL, NULL,
+                           pinfo->fd->num) && name != NULL)
+                               proto_item_append_text(hnd_item, ": %s", name);
+               }
+       }
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -3003,7 +3012,8 @@ static int SpoolssRFFPCNEX_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, FALSE, FALSE);
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
+               FALSE, FALSE);
 
        offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
                                    hf_rffpcnex_flags, &flags);
@@ -3198,26 +3208,56 @@ static int SpoolssReplyOpenPrinter_r(tvbuff_t *tvb, int offset,
        dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
-       char *pol_name;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, &hnd_item,
                TRUE, FALSE);
        
-       if (dcv->private_data)
-               pol_name = g_strdup_printf(
-                       "ReplyOpenPrinter(%s)", (char *)dcv->private_data);
-       else
-               pol_name = g_strdup("ReplyOpenPrinter handle");
+       offset = dissect_doserror(
+               tvb, offset, pinfo, tree, drep, hf_rc, &status);
 
-       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+       if (status == 0) {
 
-       g_free(pol_name);
+               /* Associate the returned printer handle with a name */
 
-       offset = dissect_doserror(
-               tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+               if (dcv->private_data) {
+                       char *pol_name;
+
+                       pol_name = g_strdup_printf(
+                               "OpenPrinter(%s)",
+                               (char *)dcv->private_data);
+
+                       dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
+
+                       g_free(pol_name);
+                       g_free(dcv->private_data);
+                       dcv->private_data = NULL;
+               }
+
+               /*
+                * If we have a name for the handle, attach it to the item.
+                *
+                * XXX - we can't just do that above, as this may be called
+                * twice (see "dissect_pipe_dcerpc()", which calls the
+                * DCE RPC dissector twice), and in the first call we're
+                * not building a protocol tree (so we don't have an item
+                * to which to attach it) and in the second call
+                * "dcv->private_data" is NULL so we don't construct a
+                * name.
+                */
+
+               if (hnd_item != NULL) {
+                       char *name;
+
+                       if (dcerpc_smb_fetch_pol(&policy_hnd, &name, NULL, NULL,
+                           pinfo->fd->num) && name != NULL)
+                               proto_item_append_text(hnd_item, ": %s", name);
+               }
+       }
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -3240,7 +3280,7 @@ static int SpoolssGetPrinter_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
@@ -3477,7 +3517,7 @@ static int SpoolssSetPrinter_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
         offset = dissect_ndr_uint32(
@@ -3596,7 +3636,7 @@ static int SpoolssEnumForms_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
         offset = dissect_ndr_uint32(
@@ -3678,7 +3718,7 @@ static int SpoolssDeletePrinter_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
@@ -3693,7 +3733,7 @@ static int SpoolssDeletePrinter_r(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_doserror(
@@ -3710,12 +3750,13 @@ static int SpoolssAddPrinterEx_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
        dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
        guint32 status;
 
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, &hnd_item,
                TRUE, FALSE);
 
        offset = dissect_doserror(
@@ -3733,11 +3774,31 @@ static int SpoolssAddPrinterEx_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                        (char *)dcv->private_data);
 
                        dcerpc_smb_store_pol_name(
-                               &policy_hnd, dcv->private_data);
+                               &policy_hnd, pinfo, dcv->private_data);
 
                        g_free(dcv->private_data);
                        dcv->private_data = NULL;
                }
+
+               /*
+                * If we have a name for the handle, attach it to the item.
+                *
+                * XXX - we can't just do that above, as this may be called
+                * twice (see "dissect_pipe_dcerpc()", which calls the
+                * DCE RPC dissector twice), and in the first call we're
+                * not building a protocol tree (so we don't have an item
+                * to which to attach it) and in the second call
+                * "dcv->private_data" is NULL so we don't construct a
+                * name.
+                */
+
+               if (hnd_item != NULL) {
+                       char *name;
+
+                       if (dcerpc_smb_fetch_pol(&policy_hnd, &name, NULL, NULL,
+                           pinfo->fd->num) && name != NULL)
+                               proto_item_append_text(hnd_item, ": %s", name);
+               }
        }
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
@@ -3768,7 +3829,7 @@ static int SpoolssEnumPrinterData_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
@@ -4118,7 +4179,7 @@ static int SpoolssAddForm_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
@@ -4169,7 +4230,7 @@ static int SpoolssDeleteForm_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
@@ -4218,7 +4279,7 @@ static int SpoolssSetForm_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
@@ -4277,7 +4338,7 @@ static int SpoolssGetForm_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
@@ -4582,7 +4643,7 @@ static int SpoolssEnumJobs_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
                tvb, offset, pinfo, tree, drep, hf_enumjobs_firstjob, NULL);
@@ -4684,7 +4745,8 @@ static int SpoolssSetJob_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, FALSE, FALSE);
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
+               FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
                tvb, offset, pinfo, tree, drep, hf_job_id, &jobid);
@@ -4733,7 +4795,8 @@ static int SpoolssGetJob_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, FALSE, FALSE);
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
+               FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
                tvb, offset, pinfo, tree, drep, hf_job_id, &jobid);
@@ -4813,10 +4876,11 @@ static int SpoolssStartPagePrinter_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, 
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, NULL,
                FALSE, FALSE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL,
+                            pinfo->fd->num);
 
        if (check_col(pinfo->cinfo, COL_INFO) && pol_name)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
@@ -4855,10 +4919,11 @@ static int SpoolssEndPagePrinter_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, NULL,
                FALSE, FALSE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL,
+                            pinfo->fd->num);
 
        if (check_col(pinfo->cinfo, COL_INFO) && pol_name)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
@@ -5012,10 +5077,11 @@ static int SpoolssStartDocPrinter_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, NULL,
                FALSE, FALSE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL,
+                            pinfo->fd->num);
 
        if (check_col(pinfo->cinfo, COL_INFO) && pol_name)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
@@ -5059,10 +5125,11 @@ static int SpoolssEndDocPrinter_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, NULL,
                FALSE, FALSE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL,
+                            pinfo->fd->num);
 
        if (check_col(pinfo->cinfo, COL_INFO) && pol_name)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
@@ -5107,10 +5174,11 @@ static int SpoolssWritePrinter_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, NULL,
                FALSE, FALSE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL,
+                            pinfo->fd->num);
 
        if (check_col(pinfo->cinfo, COL_INFO) && pol_name)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
@@ -5178,7 +5246,7 @@ static int SpoolssDeletePrinterData_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
@@ -5418,10 +5486,11 @@ static int SpoolssGetPrinterDriver2_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd,
+               tvb, offset, pinfo, tree, drep, hf_hnd, &policy_hnd, NULL,
                FALSE, FALSE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL,
+                            pinfo->fd->num);
 
        if (check_col(pinfo->cinfo, COL_INFO) && pol_name)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
@@ -6027,7 +6096,7 @@ static int SpoolssRFNPCNEX_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
@@ -6077,7 +6146,7 @@ static int SpoolssRRPCN_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
@@ -6135,7 +6204,8 @@ static int SpoolssReplyClosePrinter_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, FALSE, TRUE);
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
+               FALSE, TRUE);
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -6149,7 +6219,8 @@ static int SpoolssReplyClosePrinter_r(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, FALSE, FALSE);
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
+               FALSE, FALSE);
 
        offset = dissect_doserror(
                tvb, offset, pinfo, tree, drep, hf_rc, NULL);
@@ -6169,7 +6240,8 @@ static int SpoolssFCPN_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, FALSE, FALSE);
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
+               FALSE, FALSE);
 
        dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
 
@@ -6203,7 +6275,8 @@ static int SpoolssRouterReplyPrinter_q(tvbuff_t *tvb, int offset, packet_info *p
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, FALSE, FALSE);
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
+               FALSE, FALSE);
 
        offset = dissect_ndr_uint32(
                tvb, offset, pinfo, tree, drep,
@@ -6281,7 +6354,7 @@ static int SpoolssEnumPrinterKey_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
@@ -6349,7 +6422,7 @@ static int SpoolssEnumPrinterDataEx_q(tvbuff_t *tvb, int offset,
        /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_hnd, NULL,
+               tvb, offset, pinfo, tree, drep, hf_hnd, NULL, NULL,
                FALSE, FALSE);
 
        offset = dissect_ndr_cvstring(
index 7f9365e3d91f65b15f81eb37ac72b448805f4646..16116db4ac51c462f674d0ea467adfcba5d40046 100644 (file)
@@ -9,7 +9,7 @@
  * 2002, some share information levels implemented based on samba
  * sources.
  *
- * $Id: packet-dcerpc-srvsvc.c,v 1.56 2003/05/15 05:24:18 guy Exp $
+ * $Id: packet-dcerpc-srvsvc.c,v 1.57 2003/06/05 04:22:04 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -6440,7 +6440,7 @@ srvsvc_dissect_netrsharedelstart_reply(tvbuff_t *tvb, int offset,
                                     char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_srvsvc_hnd, NULL, TRUE, FALSE);
+                                      hf_srvsvc_hnd, NULL, NULL, TRUE, FALSE);
 
        offset = dissect_doserror(tvb, offset, pinfo, tree, drep,
                        hf_srvsvc_rc, NULL);
@@ -6459,7 +6459,7 @@ srvsvc_dissect_netrsharedelcommit_rqst(tvbuff_t *tvb, int offset,
                                     char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_srvsvc_hnd, NULL, TRUE, FALSE);
+                                      hf_srvsvc_hnd, NULL, NULL, TRUE, FALSE);
 
        return offset;
 }
@@ -6469,7 +6469,7 @@ srvsvc_dissect_netrsharedelcommit_reply(tvbuff_t *tvb, int offset,
                                     char *drep)
 {
         offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, drep,
-                                      hf_srvsvc_hnd, NULL, TRUE, FALSE);
+                                      hf_srvsvc_hnd, NULL, NULL, TRUE, FALSE);
 
        offset = dissect_doserror(tvb, offset, pinfo, tree, drep,
                        hf_srvsvc_rc, NULL);
index 92d7cdc5df0ada201c680d6b7e5ccac2a53b4e69..8db1d888b5ee90b64b7ff9742cfbc254c5082976 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright 2003, Tim Potter <tpot@samba.org>
  * Copyright 2003, Ronnie Sahlberg,  added function dissectors
  *
- * $Id: packet-dcerpc-svcctl.c,v 1.8 2003/05/15 02:14:00 tpot Exp $
+ * $Id: packet-dcerpc-svcctl.c,v 1.9 2003/06/05 04:22:04 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -145,19 +145,17 @@ svcctl_dissect_OpenSCManager_reply(tvbuff_t *tvb, int offset,
        dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
        dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
        guint32 status;
-       int start_offset = offset;
 
-       /* We need the value of the policy handle and status before we
-          can retrieve the policy handle name.  Then we can insert
-          the policy handle with the name in the proto tree. */
+       /* Parse packet */
 
        offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, NULL, drep, hf_svcctl_hnd, &policy_hnd,
-               TRUE, FALSE);
+               tvb, offset, pinfo, tree, drep, hf_svcctl_hnd, &policy_hnd,
+               &hnd_item, TRUE, FALSE);
 
-       offset = dissect_ndr_uint32(
-               tvb, offset, pinfo, NULL, drep, hf_svcctl_rc, &status);
+       offset = dissect_doserror(
+               tvb, offset, pinfo, tree, drep, hf_svcctl_rc, &status);
 
        if (status == 0) {
 
@@ -170,24 +168,33 @@ svcctl_dissect_OpenSCManager_reply(tvbuff_t *tvb, int offset,
                                "OpenSCManager(%s)", 
                                (char *)dcv->private_data);
 
-                       dcerpc_smb_store_pol_name(&policy_hnd, pol_name);
+                       dcerpc_smb_store_pol_name(&policy_hnd, pinfo, pol_name);
 
                        g_free(pol_name);
                        g_free(dcv->private_data);
                        dcv->private_data = NULL;
                }
-       }
-
-       /* Parse packet */
-
-       offset = start_offset;
 
-       offset = dissect_nt_policy_hnd(
-               tvb, offset, pinfo, tree, drep, hf_svcctl_hnd, &policy_hnd,
-               TRUE, FALSE);
-
-       offset = dissect_doserror(
-               tvb, offset, pinfo, tree, drep, hf_svcctl_rc, &status);
+               /*
+                * If we have a name for the handle, attach it to the item.
+                *
+                * XXX - we can't just do that above, as this may be called
+                * twice (see "dissect_pipe_dcerpc()", which calls the
+                * DCE RPC dissector twice), and in the first call we're
+                * not building a protocol tree (so we don't have an item
+                * to which to attach it) and in the second call
+                * "dcv->private_data" is NULL so we don't construct a
+                * name.
+                */
+
+               if (hnd_item != NULL) {
+                       char *name;
+
+                       if (dcerpc_smb_fetch_pol(&policy_hnd, &name, NULL, NULL,
+                           pinfo->fd->num) && name != NULL)
+                               proto_item_append_text(hnd_item, ": %s", name);
+               }
+       }
 
        return offset;
 }
@@ -211,9 +218,10 @@ svcctl_dissect_CloseServiceHandle_rqst(tvbuff_t *tvb, int offset,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_svcctl_hnd, &policy_hnd,
-               FALSE, TRUE);
+               NULL, FALSE, TRUE);
 
-       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL);
+       dcerpc_smb_fetch_pol(&policy_hnd, &pol_name, NULL, NULL,
+                            pinfo->fd->num);
 
        if (check_col(pinfo->cinfo, COL_INFO) && pol_name)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
@@ -229,7 +237,7 @@ svcctl_dissect_CloseServiceHandle_reply(tvbuff_t *tvb, int offset,
 {
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_svcctl_hnd, NULL,
-               FALSE, TRUE);
+               NULL, FALSE, TRUE);
 
        offset = dissect_doserror(
                tvb, offset, pinfo, tree, drep, hf_svcctl_rc, NULL);
@@ -250,9 +258,10 @@ svcctl_dissect_LockServiceDatabase_rqst(tvbuff_t *tvb, int offset,
                                  packet_info *pinfo, proto_tree *tree,
                                  char *drep)
 {
+       /* XXX - why is the "is a close" argument TRUE? */
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_svcctl_hnd, NULL,
-               FALSE, TRUE);
+               NULL, FALSE, TRUE);
 
        return offset;
 }
@@ -261,9 +270,10 @@ svcctl_dissect_LockServiceDatabase_reply(tvbuff_t *tvb, int offset,
                                  packet_info *pinfo, proto_tree *tree,
                                  char *drep)
 {
+       /* XXX - why is the "is an open" argument TRUE? */
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_svcctl_lock, NULL,
-               TRUE, FALSE);
+               NULL, TRUE, FALSE);
 
        offset = dissect_doserror(
                tvb, offset, pinfo, tree, drep, hf_svcctl_rc, NULL);
@@ -283,9 +293,10 @@ svcctl_dissect_UnlockServiceDatabase_rqst(tvbuff_t *tvb, int offset,
                                  packet_info *pinfo, proto_tree *tree,
                                  char *drep)
 {
+       /* XXX - why is the "is a close" argument TRUE? */
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_svcctl_lock, NULL,
-               FALSE, TRUE);
+               NULL, FALSE, TRUE);
 
        return offset;
 }
@@ -294,9 +305,10 @@ svcctl_dissect_UnlockServiceDatabase_reply(tvbuff_t *tvb, int offset,
                                  packet_info *pinfo, proto_tree *tree,
                                  char *drep)
 {
+       /* XXX - why is the "is an open" argument TRUE? */
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_svcctl_lock, NULL,
-               TRUE, FALSE);
+               NULL, TRUE, FALSE);
 
        offset = dissect_doserror(
                tvb, offset, pinfo, tree, drep, hf_svcctl_rc, NULL);
@@ -344,9 +356,10 @@ svcctl_dissect_QueryServiceLockStatus_rqst(tvbuff_t *tvb, int offset,
                                  packet_info *pinfo, proto_tree *tree,
                                  char *drep)
 {
+       /* XXX - why is the "is a close" argument TRUE? */
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_svcctl_hnd, NULL,
-               FALSE, TRUE);
+               NULL, FALSE, TRUE);
 
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                                      hf_svcctl_size, NULL);
@@ -405,9 +418,10 @@ svcctl_dissect_EnumServicesStatus_rqst(tvbuff_t *tvb, int offset,
                                  packet_info *pinfo, proto_tree *tree,
                                  char *drep)
 {
+       /* XXX - why is the "is a close" argument TRUE? */
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep, hf_svcctl_hnd, NULL,
-               FALSE, TRUE);
+               NULL, FALSE, TRUE);
 
         offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep,
                                      hf_svcctl_service_type, NULL);