dcerpc-netlogon: maintain netlogon_auth_vars for NetrServerAuthenticateKerberos
[wireshark-sm.git] / epan / dissectors / pidl / drsuapi / drsuapi.cnf
blob64e6925b0c51ae2f9a5a0d7578f55282aeb5f8f1
1 # Conformance file for drsuapi
3 MANUAL drsuapi_dissect_struct_DsBindInfoCtr
5 NOEMIT drsuapi_dissect_element_DsBindInfoCtr_length
7 MANUAL drsuapi_dissect_DsBindInfo
8 NOEMIT drsuapi_dissect_element_DsBindInfo_info24
9 NOEMIT drsuapi_dissect_element_DsBindInfo_info28
10 NOEMIT drsuapi_dissect_element_DsBindInfo_info32
11 NOEMIT drsuapi_dissect_element_DsBindInfo_info48
12 NOEMIT drsuapi_dissect_element_DsBindInfo_info52
13 NOEMIT drsuapi_dissect_element_DsBindInfo_Fallback
14 NOEMIT drsuapi_dissect_element_DsBindInfoCtr___ndr_length
16 MANUAL drsuapi_dissect_element_DsReplicaObjectIdentifier_sid
17 MANUAL drsuapi_dissect_element_DsReplicaAttribute_attid
18 MANUAL drsuapi_dissect_element_DsAttributeValue_blob_
19 MANUAL drsuapi_dissect_struct_DsReplicaAttribute
20 MANUAL drsuapi_dissect_struct_DsReplicaObject
21 MANUAL drsuapi_dissect_element_DsReplicaObjectListItem_next_object_
22 MANUAL drsuapi_dissect_struct_DsReplicaObjectListItem
23 MANUAL drsuapi_dissect_element_DsReplicaObjectListItemEx_next_object_
24 MANUAL drsuapi_dissect_struct_DsReplicaObjectListItemEx
25 MANUAL drsuapi_dissect_element_DsAddEntry_AttrErrListItem_V1_next_
26 MANUAL drsuapi_dissect_element_DsaAddressListItem_V1_next_
27 MANUAL drsuapi_dissect_element_DsAddEntry_RefErrListItem_V1_next_
28 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_keys
29 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_old_keys
30 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys
31 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_
32 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys
33 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_
34 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey3_value
35 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey3_value_
36 NOEMIT drsuapi_dissect_element_package_PrimaryKerberosKey3_keytype
37 NOEMIT drsuapi_dissect_element_package_PrimaryKerberosKey3_value_len
38 NOEMIT drsuapi_dissect_element_package_PrimaryKerberosKey3_value_ofs
39 MANUAL drsuapi_dissect_struct_package_PrimaryKerberosKey3
40 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_keys
41 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_service_keys
42 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_old_keys
43 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_older_keys
44 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys
45 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_
46 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys
47 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_
48 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys
49 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_
50 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys
51 MANUAL drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_
52 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey4_value
53 MANUAL drsuapi_dissect_element_package_PrimaryKerberosKey4_value_
54 NOEMIT drsuapi_dissect_element_package_PrimaryKerberosKey4_keytype
55 NOEMIT drsuapi_dissect_element_package_PrimaryKerberosKey4_value_len
56 NOEMIT drsuapi_dissect_element_package_PrimaryKerberosKey4_value_ofs
57 MANUAL drsuapi_dissect_struct_package_PrimaryKerberosKey4
58 MANUAL drsuapi_dissect_element_package_PrimaryKerberosBlob_version
59 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_name_len
60 MANUAL drsuapi_dissect_element_supplementalCredentialsPackage_data_len
61 NOEMIT drsuapi_dissect_element_supplementalCredentialsPackage_name
62 NOEMIT drsuapi_dissect_element_supplementalCredentialsPackage_data
63 MANUAL drsuapi_dissect_struct_supplementalCredentialsPackage
64 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix_
65 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages
66 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_packages
67 MANUAL drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_
68 MANUAL drsuapi_dissect_struct_supplementalCredentialsSubBlob
69 MANUAL drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size
70 MANUAL drsuapi_dissect_element_supplementalCredentialsBlob_sub
71 MANUAL drsuapi_dissect_struct_supplementalCredentialsBlob
73 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr1TS_ctr1
74 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr1TS_ctr1_
75 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr6TS_ctr6
76 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr9TS_ctr9
77 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr9TS_ctr9_
79 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr7_level
80 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr7_level
81 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr7_type
82 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr7_type
83 MANUAL drsuapi_dissect_element_DsGetNCChangesCtr7_ctr
84 NOEMIT drsuapi_dissect_element_DsGetNCChangesCtr7_ctr
85 MANUAL drsuapi_dissect_struct_DsGetNCChangesCtr7
87 MANUAL drsuapi_dissect_element_DsGetNCChangesXPRESSCtr6_ts__
88 NOEMIT drsuapi_dissect_element_DsGetNCChangesXPRESSCtr6_ts__
90 HF_FIELD hf_drsuapi_String_name "String" "drsuapi.lsa.string" FT_STRING BASE_NONE NULL 0 "" "" ""
91 MANUAL drsuapi_dissect_element_lsa_String_string_
92 NOEMIT drsuapi_dissect_element_lsa_String_string__
94 HF_FIELD hf_DsReplicaObjectIdentifier_dn "DN" "drsuapi.objectidentifier.dn" FT_STRING BASE_NONE NULL 0 "" "" ""
95 MANUAL drsuapi_dissect_element_DsReplicaObjectIdentifier_dn
96 NOEMIT drsuapi_dissect_element_DsReplicaObjectIdentifier_dn_
98 NOEMIT drsuapi_dissect_element_DsReplicaObjectIdentifier3_dn_
99 NOEMIT drsuapi_dissect_element_DsReplicaObjectIdentifier3Binary_dn_
101 NOEMIT drsuapi_dissect_element_DsBindInfoCtr_info
103 CODE START
105   #include <wsutil/wsgcrypt.h>
106   #include <epan/expert.h>
107   #include <epan/strutil.h>
108   #define KERBEROS_METZE 1
109   #include "packet-kerberos.h"
111 static int
112 drsuapi_dissect_element_DsReplicaObjectIdentifier_sid(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
114         /*manual*/
115         dcerpc_ptr_stack *ptr = di->ptr_stack;
116         int start_offset = offset;
117         uint32_t rid = 0;
119         offset = dissect_ndr_nt_SID28(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsReplicaObjectIdentifier_sid);
120         if (ptr == NULL) {
121                 return offset;
122         }
124         if (offset > start_offset) {
125                 dissect_ndr_uint32(tvb, start_offset + 24, pinfo, tree, di, drep, -1, &rid);
126         }
128         ptr->private_data.val64 = rid;
129         if (tree == NULL) return offset;
131 if (0) {
132       proto_tree_add_debug_text(tree,
133                         "METZE frame:%d drsuapi_dissect_element_DsReplicaObjectIdentifier_sid RID:%d auth_info->session_key=%s",
134                         pinfo->fd->num, rid,
135                         di->auth_session_key != NULL ?
136                         di->auth_session_key->id_str : "NO");
138         return offset;
141 static int
142 drsuapi_dissect_element_DsReplicaAttribute_attid(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
144         /*manual*/
145         dcerpc_ptr_stack *ptr = di->ptr_stack;
146         uint32_t rid = 0;
147         uint32_t attid = 0;
148         offset = drsuapi_dissect_enum_DsAttributeId(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsReplicaAttribute_attid, &attid);
149         if (ptr == NULL) {
150                 return offset;
151         }
152         if (ptr->parent == NULL) {
153                 return offset;
154         }
155         rid = ptr->parent->private_data.val64;
156         ptr->private_data.val64 = attid;
157         if (tree == NULL) return offset;
158 if (0) {
159       proto_tree_add_debug_text(tree,
160                         "METZE frame:%d drsuapi_dissect_element_DsReplicaAttribute_attid RID:%d ATTID:0x%08X auth_info->session_key=%s",
161                         pinfo->fd->num,
162                         rid, attid,
163                         di->auth_session_key != NULL ?
164                         di->auth_session_key->id_str : "NO");
166         return offset;
169 static int
170 drsuapi_dissect_element_package_PrimaryKerberosBlob_version(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *version)
172         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosBlob_version, 0, version);
174         return offset;
177 static int
178 drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_keys)
180         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr3_num_keys, 0, num_keys);
182         return offset;
185 static int
186 drsuapi_dissect_element_package_PrimaryKerberosCtr3_num_old_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_old_keys)
188         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr3_num_old_keys, 0, num_old_keys);
190         return offset;
193 static int
194 drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_keys)
196         return drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_(tvb, offset, pinfo, tree, di, drep, num_keys);
199 static int
200 drsuapi_dissect_element_package_PrimaryKerberosCtr3_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_keys)
202         uint32_t i;
204         for (i=0; i < *num_keys; i++) {
205                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr3_keys, 0);
206         }
208         return offset;
211 static int
212 drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_old_keys)
214         return drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_(tvb, offset, pinfo, tree, di, drep, num_old_keys);
217 static int
218 drsuapi_dissect_element_package_PrimaryKerberosCtr3_old_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_old_keys)
220         uint32_t i;
222         for (i=0; i < *num_old_keys; i++) {
223                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr3_old_keys, 0);
224         }
226         return offset;
229 static int
230 drsuapi_dissect_element_package_PrimaryKerberosKey3_value(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint32_t *value_len)
232         return drsuapi_dissect_element_package_PrimaryKerberosKey3_value_(tvb, offset, pinfo, tree, di, drep, value_len);
235 static int
236 drsuapi_dissect_element_package_PrimaryKerberosKey3_value_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint32_t *value_len)
238         tvbuff_t *subtvb = tvb_new_subset_length(tvb, offset, *value_len);
240         offset += dissect_ndr_datablob(subtvb, 0, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value, 1);
242         return offset;
246 drsuapi_dissect_struct_package_PrimaryKerberosKey3(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
248         uint32_t value_len = 0;
249         proto_item *item = NULL;
250         proto_tree *tree = NULL;
251         int old_offset;
252         uint32_t keytype;
253         uint32_t value_ofs;
255         ALIGN_TO_4_BYTES;
257         old_offset = offset;
259         if (parent_tree) {
260                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
261                 tree = proto_item_add_subtree(item, ett_drsuapi_package_PrimaryKerberosKey3);
262         }
264         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved1(tvb, offset, pinfo, tree, di, drep);
266         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved2(tvb, offset, pinfo, tree, di, drep);
268         offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_reserved3(tvb, offset, pinfo, tree, di, drep);
270         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_keytype(tvb, offset, pinfo, tree, di, drep);
271         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_keytype, 0, &keytype);
273         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value_len(tvb, offset, pinfo, tree, di, drep, &value_len);
274         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value_len, 0, &value_len);
276         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey3_value_ofs(tvb, offset, pinfo, tree, di, drep);
277         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey3_value_ofs, 0, &value_ofs);
279         if (value_ofs != 0 && tvb_bytes_exist(tvb, value_ofs, value_len)) {
280                 drsuapi_dissect_element_package_PrimaryKerberosKey3_value(tvb, value_ofs, pinfo, tree, di, drep, &value_len);
281         }
283         proto_item_set_len(item, offset-old_offset);
286         if (di->call_data->flags & DCERPC_IS_NDR64) {
287                 ALIGN_TO_4_BYTES;
288         }
290         return offset;
293 static int
294 drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_keys)
296         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_keys, 0, num_keys);
298         return offset;
301 static int
302 drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_service_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_service_keys)
304         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_service_keys, 0, num_service_keys);
306         return offset;
309 static int
310 drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_old_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_old_keys)
312         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_old_keys, 0, num_old_keys);
314         return offset;
317 static int
318 drsuapi_dissect_element_package_PrimaryKerberosCtr4_num_older_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_older_keys)
320         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosCtr4_num_older_keys, 0, num_older_keys);
322         return offset;
325 static int
326 drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_keys)
328         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_(tvb, offset, pinfo, tree, di, drep, num_keys);
331 static int
332 drsuapi_dissect_element_package_PrimaryKerberosCtr4_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_keys)
334         uint32_t i;
336         for (i=0; i < *num_keys; i++) {
337                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_keys, 0);
338         }
340         return offset;
343 static int
344 drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_service_keys)
346         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_(tvb, offset, pinfo, tree, di, drep, num_service_keys);
349 static int
350 drsuapi_dissect_element_package_PrimaryKerberosCtr4_service_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_service_keys)
352         uint32_t i;
354         for (i=0; i < *num_service_keys; i++) {
355                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_service_keys, 0);
356         }
358         return offset;
361 static int
362 drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_old_keys)
364         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_(tvb, offset, pinfo, tree, di, drep, num_old_keys);
367 static int
368 drsuapi_dissect_element_package_PrimaryKerberosCtr4_old_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_old_keys)
370         uint32_t i;
372         for (i=0; i < *num_old_keys; i++) {
373                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_old_keys, 0);
374         }
376         return offset;
379 static int
380 drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_older_keys)
382         return drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_(tvb, offset, pinfo, tree, di, drep, num_older_keys);
385 static int
386 drsuapi_dissect_element_package_PrimaryKerberosCtr4_older_keys_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_older_keys)
388         uint32_t i;
390         for (i=0; i < *num_older_keys; i++) {
391                 offset = drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_package_PrimaryKerberosCtr4_older_keys, 0);
392         }
394         return offset;
397 static int
398 drsuapi_dissect_element_package_PrimaryKerberosKey4_value(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint32_t *value_len)
400         return drsuapi_dissect_element_package_PrimaryKerberosKey4_value_(tvb, offset, pinfo, tree, di, drep, value_len);
403 static int
404 drsuapi_dissect_element_package_PrimaryKerberosKey4_value_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint32_t *value_len)
406         tvbuff_t *subtvb = tvb_new_subset_length(tvb, offset, *value_len);
407         dcerpc_ptr_stack *keytype_ptr = di->ptr_stack;
408         uint32_t rid = 0;
409         int keytype = 0;
410         int keylength = *value_len;
411         uint8_t keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
412         char origin[128] = {0, };
414         offset += dissect_ndr_datablob(subtvb, 0, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value, 1);
415         if (keytype_ptr == NULL) {
416                 return offset;
417         }
418         if (keytype_ptr->parent == NULL) {
419                 return offset;
420         }
422         rid = keytype_ptr->parent->private_data.val64;
423         keytype = keytype_ptr->private_data.val64;
424         tvb_memcpy(subtvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
425         snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.PrimaryKerberosKey4", rid);
427         kerberos_inject_longterm_key(pinfo, tree, NULL, subtvb,
428                                      keytype, keylength, keyvalue,
429                                      origin);
431         return offset;
435 drsuapi_dissect_struct_package_PrimaryKerberosKey4(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
437         uint32_t value_len = 0;
438         proto_item *item = NULL;
439         proto_tree *tree = NULL;
440         int old_offset;
441         uint32_t keytype;
442         uint32_t value_ofs;
444         ALIGN_TO_4_BYTES;
446         old_offset = offset;
448         if (parent_tree) {
449                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
450                 tree = proto_item_add_subtree(item, ett_drsuapi_package_PrimaryKerberosKey4);
451         }
453         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved1(tvb, offset, pinfo, tree, di, drep);
455         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved2(tvb, offset, pinfo, tree, di, drep);
457         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_reserved3(tvb, offset, pinfo, tree, di, drep);
459         offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_iteration_count(tvb, offset, pinfo, tree, di, drep);
461         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_keytype(tvb, offset, pinfo, tree, di, drep);
462         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_keytype, 0, &keytype);
464         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value_len(tvb, offset, pinfo, tree, di, drep, &value_len);
465         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value_len, 0, &value_len);
467         //offset = drsuapi_dissect_element_package_PrimaryKerberosKey4_value_ofs(tvb, offset, pinfo, tree, di, drep);
468         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_package_PrimaryKerberosKey4_value_ofs, 0, &value_ofs);
470         if (value_ofs != 0 && tvb_bytes_exist(tvb, value_ofs, value_len)) {
471                 dcerpc_ptr_stack *rid_ptr = di->ptr_stack;
472                 dcerpc_ptr_stack *keytype_ptr = NULL;
474                 if (rid_ptr != NULL) {
475                         keytype_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
476                 }
478                 if (keytype_ptr != NULL) {
479                         keytype_ptr->parent = rid_ptr;
480                         keytype_ptr->private_data.val64 = keytype;
481                 }
482                 di->ptr_stack = keytype_ptr;
483                 drsuapi_dissect_element_package_PrimaryKerberosKey4_value(tvb, value_ofs, pinfo, tree, di, drep, &value_len);
484                 di->ptr_stack = rid_ptr;
485         }
487         proto_item_set_len(item, offset-old_offset);
489         if (di->call_data->flags & DCERPC_IS_NDR64) {
490                 ALIGN_TO_4_BYTES;
491         }
493         return offset;
495 static int
496 drsuapi_dissect_package_PrimaryKerberosBlob(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
498         uint8_t drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
499         static dcerpc_info di = {0, };      /* fake dcerpc_info struct */
500         static dcerpc_call_value call_data = { 0, };
501         int offset;
503         /* fake whatever state the dcerpc runtime support needs */
504         di.conformant_run=0;
505         /* we need di->call_data->flags.NDR64 == 0 */
506         di.call_data=&call_data;
507         init_ndr_pointer_list(&di);
508         di.ptr_stack = parent_di->ptr_stack;
509         offset = drsuapi_dissect_struct_package_PrimaryKerberosBlob(tvb, 0, pinfo, parent_tree, &di, drep,
510                                 hf_drsuapi_pkb_PrimaryKerberosBlob, 0);
511         free_ndr_pointer_list(&di);
512         return offset;
515 typedef int (*package_dissector_fn_t)(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_);
517 static bool
518 drsuapi_GByteArray_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_)
520         GByteArray *bytes = (GByteArray *)user_data;
521         g_byte_array_free(bytes, TRUE);
522         /* unregister this callback */
523         return false;
526 static int
527 drsuapi_dissect_element_supplementalCredentialsPackage_name_len(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *name_len)
529         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsPackage_name_len, 0, name_len);
531         return offset;
534 static int
535 drsuapi_dissect_element_supplementalCredentialsPackage_data_len(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *data_len)
537         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsPackage_data_len, 0, data_len);
539         return offset;
542 drsuapi_dissect_struct_supplementalCredentialsPackage(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
544         proto_item *item = NULL;
545         proto_tree *tree = NULL;
546         int old_offset;
547         uint16_t name_len = 0;
548         const char *name = NULL;
549         uint16_t data_len = 0;
551         ALIGN_TO_2_BYTES;
553         old_offset = offset;
555         if (parent_tree) {
556                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
557                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsPackage);
558         }
560         offset = drsuapi_dissect_element_supplementalCredentialsPackage_name_len(tvb, offset, pinfo, tree, di, drep, &name_len);
561         offset = drsuapi_dissect_element_supplementalCredentialsPackage_data_len(tvb, offset, pinfo, tree, di, drep, &data_len);
562         offset = drsuapi_dissect_element_supplementalCredentialsPackage_reserved(tvb, offset, pinfo, tree, di, drep);
563 if (0) {
564  #if 0
565         offset = drsuapi_dissect_element_supplementalCredentialsPackage_name(tvb, offset, pinfo, tree, di, drep, &name_len);
566  #endif
567 } else {
568         const uint8_t *_name = NULL;
569         proto_tree_add_item_ret_string(tree, hf_drsuapi_supplementalCredentialsPackage_name,
570                                        tvb, offset, name_len, ENC_UTF_16|ENC_LITTLE_ENDIAN,
571                                        wmem_packet_scope(), &_name);
572         name = (const char *)_name;
573         proto_item_append_text(item, ": %s", name);
574         offset += name_len;
576 if (0) {
577  #if 0
578         offset = drsuapi_dissect_element_supplementalCredentialsPackage_data(tvb, offset, pinfo, tree, di, drep, &data_len);
579  #endif
580 } else {
581         const uint8_t *_hexdata = NULL;
582         const char *hexdata = NULL;
583         tvbuff_t *tvbdata = NULL;
584         proto_tree_add_item_ret_string(tree, hf_drsuapi_supplementalCredentialsPackage_data,
585                                        tvb, offset, data_len, ENC_ASCII,
586                                        wmem_packet_scope(), &_hexdata);
587         hexdata = (const char *)_hexdata;
588         if (hexdata != NULL) {
589                 GByteArray *bytes = NULL;
591                 /* Convert key to raw bytes */
592                 bytes = g_byte_array_new();
593                 if (bytes != NULL) {
594                         gboolean res;
596                         wmem_register_callback(pinfo->pool, drsuapi_GByteArray_destroy_cb, bytes);
598                         res = hex_str_to_bytes(hexdata, bytes, FALSE);
599                         if (res) {
600                                 tvbdata = tvb_new_child_real_data(tvb,
601                                                                   bytes->data,
602                                                                   bytes->len,
603                                                                   bytes->len);
604                         }
605                 }
606         }
608         if (tvbdata != NULL) {
609                 struct {
610                         const char *name;
611                         package_dissector_fn_t fn;
612                 } packages[] = {
613                 {
614                         .name = "Primary:Kerberos-Newer-Keys",
615                         .fn = drsuapi_dissect_package_PrimaryKerberosBlob,
616                 },{
617                         .name = "Primary:Kerberos",
618                         .fn = drsuapi_dissect_package_PrimaryKerberosBlob,
619                 },{
620                         .name = NULL,
621                 }
622                 };
623                 size_t i = 0;
625                 for (i=0; packages[i].name != NULL; i++) {
626                         int cmp;
628                         cmp = strcmp(packages[i].name, name);
629                         if (cmp == 0) {
630                                 break;
631                         }
632                 }
634                 add_new_data_source(pinfo, tvbdata, name);
635                 proto_tree_add_text_internal(tree, tvbdata, 0, -1, "%s", name);
637                 if (packages[i].fn != NULL) {
638                         packages[i].fn(tvbdata, pinfo, tree, di);
639                 }
640         }
642         offset += data_len;
645         proto_item_set_len(item, offset-old_offset);
648         if (di->call_data->flags & DCERPC_IS_NDR64) {
649                 ALIGN_TO_2_BYTES;
650         }
652         return offset;
654 static int
655 drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
657         offset += 2; //PIDL_dissect_uint16(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsSubBlob_prefix, 0);
659         return offset;
662 static int
663 drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_packages)
665         offset = PIDL_dissect_uint16_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsSubBlob_num_packages, 0, num_packages);
667         return offset;
670 static int
671 drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_packages)
673         uint16_t i;
675         for (i=0; i<*num_packages; i++) {
676                 offset = drsuapi_dissect_struct_supplementalCredentialsPackage(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_supplementalCredentialsSubBlob_packages,0);
677         }
679         return offset;
682 static int
683 drsuapi_dissect_element_supplementalCredentialsSubBlob_packages(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *num_packages)
685         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_packages_(tvb,offset,pinfo,tree,di,drep,num_packages);
687         return offset;
691 drsuapi_dissect_struct_supplementalCredentialsSubBlob(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
693         proto_item *item = NULL;
694         proto_tree *tree = NULL;
695         int old_offset;
696         uint16_t num_packages;
697         unsigned remaining;
699         ALIGN_TO_3_BYTES;
701         old_offset = offset;
703         if (parent_tree) {
704                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
705                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsSubBlob);
706         }
708         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_prefix(tvb, offset, pinfo, tree, di, drep);
710         offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_signature(tvb, offset, pinfo, tree, di, drep);
712         remaining = tvb_reported_length_remaining(tvb, offset);
713         if (remaining != 0) {
714                 /*
715                  * These are optional
716                  */
717                 offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_num_packages(tvb, offset, pinfo, tree, di, drep, &num_packages);
719                 offset = drsuapi_dissect_element_supplementalCredentialsSubBlob_packages(tvb, offset, pinfo, tree, di, drep, &num_packages);
720         }
722         proto_item_set_len(item, offset-old_offset);
725         if (di->call_data->flags & DCERPC_IS_NDR64) {
726                 ALIGN_TO_3_BYTES;
727         }
729         return offset;
732 static int
733 drsuapi_dissect_element_supplementalCredentialsBlob_sub(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
735         int conformant = di->conformant_run;
736         tvbuff_t *subtvb;
738         if (!conformant) {
739                 uint32_t saved_flags = di->call_data->flags;
740                 dcerpc_ptr_stack *ndr_size_ptr = di->ptr_stack;
741                 uint32_t size = 0;
742                 if (ndr_size_ptr != NULL) {
743                         size = ndr_size_ptr->private_data.val64;
744                         di->ptr_stack = ndr_size_ptr->parent;
745                 }
746                 di->call_data->flags &= ~DCERPC_IS_NDR64;
747                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const int)size, -1);
748                 drsuapi_dissect_element_supplementalCredentialsBlob_sub_(subtvb, 0, pinfo, tree, di, drep);
749                 offset += (int)size;
750                 di->call_data->flags = saved_flags;
751                 di->ptr_stack = ndr_size_ptr;
752         }
754         return offset;
757 static int
758 drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
760         dcerpc_ptr_stack *ndr_size_ptr = di->ptr_stack;
761         uint32_t ndr_size = 0;
763         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_supplementalCredentialsBlob___ndr_size, 0, &ndr_size);
764         if (ndr_size_ptr != NULL) {
765                 ndr_size_ptr->private_data.val64 = ndr_size;
766         }
768         return offset;
772 drsuapi_dissect_struct_supplementalCredentialsBlob(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
774         /*manual*/
775         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
776         dcerpc_ptr_stack *ndr_size_ptr = NULL;
777         proto_item *item = NULL;
778         proto_tree *tree = NULL;
779         int old_offset;
781         ALIGN_TO_4_BYTES;
783         old_offset = offset;
785         if (parent_tree) {
786                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
787                 tree = proto_item_add_subtree(item, ett_drsuapi_supplementalCredentialsBlob);
788         }
790         ndr_size_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
791         if (ndr_size_ptr != NULL) {
792                 ndr_size_ptr->parent = saved_ptr;
793         }
794         di->ptr_stack = ndr_size_ptr;
796         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown1(tvb, offset, pinfo, tree, di, drep);
798         offset = drsuapi_dissect_element_supplementalCredentialsBlob___ndr_size(tvb, offset, pinfo, tree, di, drep);
800         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown2(tvb, offset, pinfo, tree, di, drep);
802         offset = drsuapi_dissect_element_supplementalCredentialsBlob_sub(tvb, offset, pinfo, tree, di, drep);
804         offset = drsuapi_dissect_element_supplementalCredentialsBlob_unknown3(tvb, offset, pinfo, tree, di, drep);
806         di->ptr_stack = saved_ptr;
808         proto_item_set_len(item, offset-old_offset);
811         if (di->call_data->flags & DCERPC_IS_NDR64) {
812                 ALIGN_TO_4_BYTES;
813         }
815         return offset;
817 static int
818 drsuapi_dissect_supplementalCredentials(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
820         uint8_t drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
821         static dcerpc_info di = {0, };      /* fake dcerpc_info struct */
822         static dcerpc_call_value call_data = { 0, };
823         int offset;
825         /* fake whatever state the dcerpc runtime support needs */
826         di.conformant_run=0;
827         /* we need di->call_data->flags.NDR64 == 0 */
828         di.call_data=&call_data;
829         init_ndr_pointer_list(&di);
830         di.ptr_stack = parent_di->ptr_stack;
831         offset = drsuapi_dissect_struct_supplementalCredentialsBlob(tvb, 0, pinfo, parent_tree, &di, drep,
832                                 hf_drsuapi_sch_supplementalCredentials, 0);
833         free_ndr_pointer_list(&di);
834         return offset;
837 static int
838 drsuapi_dissect_unicodePwd(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
840         int offset = 0;
841         dcerpc_ptr_stack *ptr = parent_di->ptr_stack;
842         uint32_t rid = 0;
843         int keytype = 23;
844         int keylength = 16;
845         tvbuff_t *keytvb = tvb_new_subset_length(tvb, offset, keylength);
846         uint8_t keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
847         char origin[128] = {0, };
849         if (ptr != NULL) {
850                 rid = ptr->private_data.val64;
851         }
853         tvb_memcpy(keytvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
854         snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.unicodePwd", rid);
856         kerberos_inject_longterm_key(pinfo, parent_tree, NULL, keytvb,
857                                      keytype, keylength, keyvalue,
858                                      origin);
859         offset += 16;
861         return offset;
864 static int
865 drsuapi_dissect_ntPwdHistory(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_)
867         dcerpc_ptr_stack *ptr = parent_di->ptr_stack;
868         uint32_t rid = 0;
869         unsigned num_hashes = tvb_reported_length(tvb)/16;
870         unsigned idx;
871         int offset = 0;
873         if (ptr != NULL) {
874                 rid = ptr->private_data.val64;
875         }
877         for (idx = 0; idx < num_hashes; idx++) {
878                 int keytype = 23;
879                 int keylength = 16;
880                 tvbuff_t *keytvb = tvb_new_subset_length(tvb, offset, keylength);
881                 uint8_t keyvalue[KRB_MAX_KEY_LENGTH] = {0,};
882                 char origin[128] = {0, };
884                 tvb_memcpy(keytvb, keyvalue, 0, MIN(keylength, KRB_MAX_KEY_LENGTH));
885                 snprintf(origin, sizeof(origin)-1, "RID=%u drsuapi.ntPwdHistory[%u]", rid, idx);
887                 kerberos_inject_longterm_key(pinfo, parent_tree, NULL, keytvb,
888                                              keytype, keylength, keyvalue,
889                                              origin);
890                 offset += 16;
891         }
893         return offset;
896 typedef int (*attr_dissector_fn_t)(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* parent_di _U_);
898 static int
899 drsuapi_dissect_element_DsAttributeValue_blob_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
901         /*manual*/
902         dcerpc_ptr_stack *ptr = di->ptr_stack;
903         uint32_t rid = 0;
904         uint32_t attid = 0;
905         int start_offset = offset;
906         int length;
907         uint8_t _confounder[16] = { 0, };
908         uint8_t *confounder;
909         uint8_t decryption_key[HASH_MD5_LENGTH] = { 0, };
910         gcry_cipher_hd_t rc4_handle = NULL;
911         gcry_buffer_t iov[2] = { {0, },};
912         gcry_error_t err;
913         uint8_t *buf = NULL;
914         int buf_len;
915         uint8_t *payload_buf = NULL;
916         int payload_len = 0;
917         tvbuff_t *payload_tvb = NULL;
918         gboolean rid_crypt = FALSE;
919         const char *attr_name = NULL;
920         attr_dissector_fn_t attr_dissector_fn = NULL;
921         char source_name[64] = { 0,};
923         offset = dissect_ndr_datablob(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsAttributeValue_blob, 0);
924         if (ptr == NULL) {
925                 return offset;
926         }
927         if (ptr->parent == NULL) {
928                 return offset;
929         }
931 // TODO check dissect_ndr_lm_nt_hash_cb...
932         rid = ptr->parent->private_data.val64;
933         attid = ptr->private_data.val64;
935         switch (attid) {
936         case DRSUAPI_ATTID_dBCSPwd:
937                 attr_name = "dBCSPwd";
938                 rid_crypt = TRUE;
939                 break;
940         case DRSUAPI_ATTID_unicodePwd:
941                 attr_name = "unicodePwd";
942                 attr_dissector_fn = drsuapi_dissect_unicodePwd;
943                 rid_crypt = TRUE;
944                 break;
945         case DRSUAPI_ATTID_ntPwdHistory:
946                 attr_name = "ntPwdHistory";
947                 attr_dissector_fn = drsuapi_dissect_ntPwdHistory;
948                 rid_crypt = TRUE;
949                 break;
950         case DRSUAPI_ATTID_lmPwdHistory:
951                 attr_name = "lmPwdHistory";
952                 rid_crypt = TRUE;
953                 break;
954         case DRSUAPI_ATTID_supplementalCredentials:
955                 attr_name = "supplementalCredentials";
956                 attr_dissector_fn = drsuapi_dissect_supplementalCredentials;
957                 break;
958         case DRSUAPI_ATTID_priorValue:
959                 attr_name = "priorValue";
960                 break;
961         case DRSUAPI_ATTID_currentValue:
962                 attr_name = "currentValue";
963                 break;
964         case DRSUAPI_ATTID_trustAuthOutgoing:
965                 attr_name = "trustAuthOutgoing";
966                 break;
967         case DRSUAPI_ATTID_trustAuthIncoming:
968                 attr_name = "trustAuthIncoming";
969                 break;
970         case DRSUAPI_ATTID_initialAuthOutgoing:
971                 attr_name = "initialAuthOutgoing";
972                 break;
973         case DRSUAPI_ATTID_initialAuthIncoming:
974                 attr_name = "initialAuthIncoming";
975                 break;
976         default:
977                 return offset;
978         }
980         length = offset - start_offset;
982         if (length < 24) {
983                 return offset;
984         }
985         start_offset += 4;
986         length -= 4;
988 if (0) {
989         proto_tree_add_text_internal(tree, tvb, start_offset, length,
990                         "METZE rid_crypt:%s RID:%d ATTID:0x%08X ATTR[%s] length=%d session_key=%s",
991                         rid_crypt ? "YES" : "NO",
992                         rid, attid, attr_name,
993                         length,
994                         di->auth_session_key != NULL ?
995                         di->auth_session_key->id_str : "NO");
998         if (di->auth_session_key == NULL) {
999                 return offset;
1000         }
1002         if (!tvb_bytes_exist(tvb, start_offset, length)) {
1003                 return offset;
1004         }
1006         confounder = tvb_memcpy(tvb, _confounder, start_offset, 16);
1007         buf_len = length - 16;
1008         buf = tvb_memdup(pinfo->pool, tvb, start_offset + 16, buf_len);
1009         if (buf == NULL) {
1010                 return offset;
1011         }
1013         iov[0].len = di->auth_session_key->keylength;
1014         iov[0].data = di->auth_session_key->keyvalue;
1015         iov[1].len = 16;
1016         iov[1].data = confounder;
1018         err = gcry_md_hash_buffers(GCRY_MD_MD5, 0, decryption_key, iov, 2);
1019         if (err != 0) {
1020                 ws_warning("GCRY: gcry_md_hash_buffers(GCRY_MD_MD5) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1021                 return offset;
1022         }
1024         err = gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
1025         if (err != 0) {
1026                 ws_warning("GCRY: gcry_cipher_open(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1027                 return offset;
1028         }
1029         err = gcry_cipher_setkey(rc4_handle, decryption_key, HASH_MD5_LENGTH);
1030         if (err != 0) {
1031                 ws_warning("GCRY: gcry_cipher_setkey(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1032                 gcry_cipher_close(rc4_handle);
1033                 return offset;
1034         }
1036         err = gcry_cipher_decrypt(rc4_handle, buf, buf_len, NULL, 0);
1037         if (err != 0) {
1038                 ws_warning("GCRY: gcry_cipher_decrypt(GCRY_CIPHER_ARCFOUR) - %s/%s\n", gcry_strsource(err), gcry_strerror(err));
1039                 gcry_cipher_close(rc4_handle);
1040                 return offset;
1041         }
1042         gcry_cipher_close(rc4_handle);
1044         payload_buf = buf + 4;
1045         payload_len = buf_len - 4;
1047         if (rid_crypt && rid != 0) {
1048                 uint8_t rk[14];
1049                 uint8_t ri = 0;
1050                 uint8_t *hb = payload_buf;
1051                 uint32_t hl = payload_len;
1052                 uint32_t hi;
1054                 /*
1055                  * We have a payload contains one or more
1056                  * NT Hashes (16 bytes each).
1057                  */
1058                 if ((hl % 16) != 0) {
1059                         return offset;
1060                 }
1062                 /*
1063                  * We build a 112 bit key based on the RID
1064                  *
1065                  * With that we need to decrypt each NT Hash (16 byte)
1066                  *
1067                  * DES is based on 8 byte blocks, which mean
1068                  * we can use the first 7 bytes (56Bit) of the key to
1069                  * decrypt the first 8 bytes of the NT Hash and
1070                  * the last 7 bytes (also 56Bit) of the key to
1071                  * decrypt the 2nd 8 bytes of the NT Hash.
1072                  */
1074                 rk[0] = rk[4] = rk[8] = rk[12] = (uint8_t)(rid & 0xFF);
1075                 rk[1] = rk[5] = rk[9] = rk[13] = (uint8_t)((rid >> 8) & 0xFF);
1076                 rk[2] = rk[6] = rk[10]         = (uint8_t)((rid >> 16) & 0xFF);
1077                 rk[3] = rk[7] = rk[11]         = (uint8_t)((rid >> 24) & 0xFF);
1079                 /* loop in 8 byte steps and toggle the key index between 0 and 7 */
1080                 for (hi=0, ri = 0; hi < hl; hi += 8, ri = ri == 0 ? 7 : 0) {
1081                         uint8_t *h64 = &hb[hi];
1082                         uint8_t *rk56 = &rk[ri];
1083                         uint8_t tmp64[8];
1084                         memcpy(tmp64, h64, 8);
1085                         decrypt_des_ecb(h64, tmp64, rk56);
1086                 }
1087         }
1089         payload_tvb = tvb_new_child_real_data(tvb, payload_buf, payload_len, payload_len);
1091         snprintf(source_name, sizeof(source_name)-1, "DRSUAPI Decrypted %s RID=%u", attr_name, rid);
1092         add_new_data_source(pinfo, payload_tvb, source_name);
1093         proto_tree_add_text_internal(tree, payload_tvb, 0, payload_len, "%s", source_name);
1095         if (attr_dissector_fn == NULL) {
1096                 return offset;
1097         }
1099         di->ptr_stack = ptr->parent;
1100         attr_dissector_fn(payload_tvb, pinfo, tree, di);
1101         di->ptr_stack = ptr;
1103         return offset;
1107 drsuapi_dissect_struct_DsReplicaAttribute(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
1109         /*manual*/
1110         dcerpc_ptr_stack *rid_ptr = di->ptr_stack;
1111         proto_item *item = NULL;
1112         proto_tree *tree = NULL;
1113         int old_offset;
1115         ALIGN_TO_5_BYTES;
1117         old_offset = offset;
1119         if (parent_tree) {
1120                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1121                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaAttribute);
1122         }
1124         if (rid_ptr != NULL) {
1125                 dcerpc_ptr_stack *attid_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
1126                 if (attid_ptr != NULL) {
1127                         attid_ptr->parent = rid_ptr;
1128                 }
1129                 di->ptr_stack = attid_ptr;
1130         }
1132         offset = drsuapi_dissect_element_DsReplicaAttribute_attid(tvb, offset, pinfo, tree, di, drep);
1134         offset = drsuapi_dissect_element_DsReplicaAttribute_value_ctr(tvb, offset, pinfo, tree, di, drep);
1136         di->ptr_stack = rid_ptr;
1138         proto_item_set_len(item, offset-old_offset);
1141         if (di->call_data->flags & DCERPC_IS_NDR64) {
1142                 ALIGN_TO_5_BYTES;
1143         }
1145         return offset;
1149 drsuapi_dissect_struct_DsReplicaObject(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
1151         /*manual*/
1152         dcerpc_ptr_stack *saved_ptr = di->ptr_stack;
1153         dcerpc_ptr_stack *rid_ptr = NULL;
1154         proto_item *item = NULL;
1155         proto_tree *tree = NULL;
1156         int old_offset;
1158         ALIGN_TO_5_BYTES;
1160         old_offset = offset;
1162         if (parent_tree) {
1163                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1164                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaObject);
1165         }
1167         rid_ptr = wmem_new0(pinfo->pool, dcerpc_ptr_stack);
1168         di->ptr_stack = rid_ptr;
1170         offset = drsuapi_dissect_element_DsReplicaObject_identifier(tvb, offset, pinfo, tree, di, drep);
1172         offset = drsuapi_dissect_element_DsReplicaObject_flags(tvb, offset, pinfo, tree, di, drep);
1174         offset = drsuapi_dissect_element_DsReplicaObject_attribute_ctr(tvb, offset, pinfo, tree, di, drep);
1176         di->ptr_stack = saved_ptr;
1178         proto_item_set_len(item, offset-old_offset);
1181         if (di->call_data->flags & DCERPC_IS_NDR64) {
1182                 ALIGN_TO_5_BYTES;
1183         }
1185         return offset;
1188 static int
1189 drsuapi_dissect_element_DsReplicaObjectListItem_next_object_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1191         offset = drsuapi_dissect_struct_DsReplicaObjectListItem(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsReplicaObjectListItem_next_object,0);
1193         return offset;
1197 drsuapi_dissect_struct_DsReplicaObjectListItem(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
1199         proto_item *item = NULL;
1200         proto_tree *tree = NULL;
1201         proto_tree *next_object_tree = NULL;
1202         int old_offset;
1204         ALIGN_TO_5_BYTES;
1206         old_offset = offset;
1208         if (parent_tree) {
1209                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1210                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaObjectListItem);
1211                 next_object_tree = proto_tree_get_parent_tree(parent_tree);
1212         }
1214         offset = drsuapi_dissect_element_DsReplicaObjectListItem_next_object(tvb, offset, pinfo, next_object_tree, di, drep);
1216         offset = drsuapi_dissect_element_DsReplicaObjectListItem_object(tvb, offset, pinfo, tree, di, drep);
1219         proto_item_set_len(item, offset-old_offset);
1222         if (di->call_data->flags & DCERPC_IS_NDR64) {
1223                 ALIGN_TO_5_BYTES;
1224         }
1226         return offset;
1229 static int
1230 drsuapi_dissect_element_DsReplicaObjectListItemEx_next_object_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1232         offset = drsuapi_dissect_struct_DsReplicaObjectListItemEx(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsReplicaObjectListItemEx_next_object,0);
1234         return offset;
1238 drsuapi_dissect_struct_DsReplicaObjectListItemEx(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
1240         proto_item *item = NULL;
1241         proto_tree *tree = NULL;
1242         proto_tree *next_object_tree = NULL;
1243         int old_offset;
1245         ALIGN_TO_5_BYTES;
1247         old_offset = offset;
1249         if (parent_tree) {
1250                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1251                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsReplicaObjectListItemEx);
1252                 next_object_tree = proto_tree_get_parent_tree(parent_tree);
1253         }
1255         offset = drsuapi_dissect_element_DsReplicaObjectListItemEx_next_object(tvb, offset, pinfo, next_object_tree, di, drep);
1257         offset = drsuapi_dissect_element_DsReplicaObjectListItemEx_object(tvb, offset, pinfo, tree, di, drep);
1259         offset = drsuapi_dissect_element_DsReplicaObjectListItemEx_is_nc_prefix(tvb, offset, pinfo, tree, di, drep);
1261         offset = drsuapi_dissect_element_DsReplicaObjectListItemEx_parent_object_guid(tvb, offset, pinfo, tree, di, drep);
1263         offset = drsuapi_dissect_element_DsReplicaObjectListItemEx_meta_data_ctr(tvb, offset, pinfo, tree, di, drep);
1266         proto_item_set_len(item, offset-old_offset);
1269         if (di->call_data->flags & DCERPC_IS_NDR64) {
1270                 ALIGN_TO_5_BYTES;
1271         }
1273         return offset;
1275 static int
1276 drsuapi_dissect_element_DsAddEntry_AttrErrListItem_V1_next_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1278         offset = drsuapi_dissect_struct_DsAddEntry_AttrErrListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsAddEntry_AttrErrListItem_V1_next,0);
1280         return offset;
1283 static int
1284 drsuapi_dissect_element_DsaAddressListItem_V1_next_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1286         offset = drsuapi_dissect_struct_DsaAddressListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsaAddressListItem_V1_next,0);
1288         return offset;
1291 static int
1292 drsuapi_dissect_element_DsAddEntry_RefErrListItem_V1_next_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1294         offset = drsuapi_dissect_struct_DsAddEntry_RefErrListItem_V1(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsAddEntry_RefErrListItem_V1_next,0);
1296         return offset;
1299 static int
1300 drsuapi_dissect_element_lsa_String_string_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di, uint8_t *drep _U_)
1302         char *data;
1304         offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep, sizeof(uint16_t), hf_drsuapi_String_name, FALSE, &data);
1305         proto_item_append_text(tree, ": %s", data);
1307         return offset;
1310 static int
1311 drsuapi_dissect_element_DsReplicaObjectIdentifier_dn(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, struct ndr_generic_array *nga)
1313         proto_tree *parent_tree = NULL;
1314         char *data = NULL;
1315         unsigned parent_level = 0;
1317         offset = dissect_ndr_generic_array_string(tvb, offset, pinfo, tree, di, drep,
1318                                                   sizeof(uint16_t), hf_DsReplicaObjectIdentifier_dn,
1319                                                   FALSE, nga, &data);
1320         if (tree == NULL) {
1321                 return offset;
1322         }
1324         parent_tree = tree;
1325         for (parent_level = 1, parent_tree = tree;
1326              parent_tree != NULL && parent_level < 10;
1327              parent_level++,
1328              parent_tree = proto_tree_get_parent_tree(parent_tree))
1329         {
1330                 proto_item *parent_item = proto_tree_get_parent(parent_tree);
1331                 field_info *fi = NULL;
1333                 if (parent_item == NULL) {
1334                         break;
1335                 }
1337                 fi = PITEM_FINFO(parent_item);
1338                 if (fi == NULL) {
1339                         break;
1340                 }
1342                 if (parent_level > 3) {
1344                 }
1345                 proto_item_append_text(parent_tree, "[%u][%s]: %s", parent_level, fi->hfinfo->name, data);
1346                 if (parent_level > 4) {
1347                         break;
1348                 }
1349         }
1351         return offset;
1354 /* IDL: struct { */
1355 /* IDL:         [range(1,10000)] uint32 length; */
1356 /* IDL:         [size_is(length)] uint8 data[*]; */
1357 /* IDL: } */
1359 static int
1360 drsuapi_dissect_element_DsBindInfoCtr_length_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1362         offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsBindInfoCtr_length, 0);
1364         return offset;
1367 static int
1368 drsuapi_dissect_DsBindInfo(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_);
1370 static int
1371 drsuapi_dissect_element_DsBindInfoCtr_data_(tvbuff_t *tvb, int offset, int length, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, uint8_t *drep)
1373         offset = drsuapi_dissect_DsBindInfo(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsBindInfoCtr_info, length);
1375         return offset;
1378 static int
1379 drsuapi_dissect_element_DsBindInfoCtr_data(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1381         offset = dissect_ndr_ucarray_block(tvb, offset, pinfo, tree, di, drep, drsuapi_dissect_element_DsBindInfoCtr_data_);
1383         return offset;
1387 drsuapi_dissect_struct_DsBindInfoCtr(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
1389         proto_item *item = NULL;
1390         proto_tree *tree = NULL;
1391         int old_offset;
1393         ALIGN_TO_4_BYTES;
1395         old_offset = offset;
1397         if (parent_tree) {
1398                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1399                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsBindInfoCtr);
1400         }
1402         offset = drsuapi_dissect_element_DsBindInfoCtr_length_(tvb, offset, pinfo, tree, di, drep);
1404         offset = drsuapi_dissect_element_DsBindInfoCtr_data(tvb, offset, pinfo, tree, di, drep);
1407         proto_item_set_len(item, offset-old_offset);
1409         if (di->call_data->flags & DCERPC_IS_NDR64) {
1410                 ALIGN_TO_4_BYTES;
1411         }
1413         return offset;
1416 static int
1417 drsuapi_dissect_DsBindInfo(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
1419         proto_item *item = NULL;
1420         proto_tree *tree = NULL;
1421         int old_offset;
1422         uint32_t length = param;
1424         old_offset = offset;
1425         if (parent_tree) {
1426                 tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_drsuapi_drsuapi_DsBindInfo, &item, "drsuapi_DsBindInfo");
1427         }
1429         if (length >= 52) {
1430                 drsuapi_dissect_struct_DsBindInfo52(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info52,0);
1431         } else if (length >= 48) {
1432                 drsuapi_dissect_struct_DsBindInfo48(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info48,0);
1433         } else if (length >= 32) {
1434                 drsuapi_dissect_struct_DsBindInfo32(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info32,0);
1435         } else if (length >= 28) {
1436                 drsuapi_dissect_struct_DsBindInfo28(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info28,0);
1437         } else if (length >= 24) {
1438                 drsuapi_dissect_struct_DsBindInfo24(tvb,offset,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsBindInfo_info24,0);
1439         }
1440         offset += length;
1441         proto_item_set_len(item, offset-old_offset);
1443         return offset;
1446 static int
1447 drsuapi_dissect_element_DsGetNCChangesCtr1TS_ctr1(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1450         uint64_t size;
1451         int conformant = di->conformant_run;
1452         tvbuff_t *subtvb = NULL;
1454         if (!conformant) {
1455                 uint32_t saved_flags = di->call_data->flags;
1456                 offset = dissect_ndr_uint3264(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr1TS_ctr1_, &size);
1457                 di->call_data->flags &= ~DCERPC_IS_NDR64;
1458                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const int)size, -1);
1459                 drsuapi_dissect_element_DsGetNCChangesCtr1TS_ctr1_(subtvb, 0, pinfo, tree, di, drep);
1460                 offset += (int)size;
1461                 di->call_data->flags = saved_flags;
1462         }
1464         return offset;
1467 static int
1468 drsuapi_dissect_element_DsGetNCChangesCtr6TS_ctr6(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1470         uint8_t ddrep[4] = { 0x10, 0x00, 0x00, 0x00};
1471         dcerpc_call_value call_data = { .flags = 0, };
1472         dcerpc_info ddi = { .call_data = &call_data, };
1473         uint64_t size;
1474         tvbuff_t *subtvb = NULL;
1475         int orig_offset = offset;
1477         offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &ddrep[0]);
1478         size = tvb_get_letoh64(tvb, orig_offset+8);
1479         subtvb = tvb_new_subset_length_caplen(tvb, offset, (int)size, (int)size);
1480         offset += (int)size;
1481         init_ndr_pointer_list(&ddi);
1482         dissect_ndr_pointer(subtvb, 0, pinfo, tree, &ddi, ddrep,
1483                             drsuapi_dissect_element_DsGetNCChangesCtr6TS_ctr6_,
1484                             NDR_POINTER_REF,
1485                             "Ctr6", -1);
1486         free_ndr_pointer_list(&ddi);
1488         return offset;
1491 static int
1492 drsuapi_dissect_element_DsGetNCChangesCtr9TS_ctr9(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1495         uint64_t size;
1496         int conformant = di->conformant_run;
1497         tvbuff_t *subtvb;
1499         if (!conformant) {
1500                 uint32_t saved_flags = di->call_data->flags;
1501                 offset = dissect_ndr_uint3264(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr6TS_ctr6_, &size);
1502                 di->call_data->flags &= ~DCERPC_IS_NDR64;
1503                 subtvb = tvb_new_subset_length_caplen(tvb, offset, (const int)size, -1);
1504                 drsuapi_dissect_element_DsGetNCChangesCtr9TS_ctr9_(subtvb, 0, pinfo, tree, di, drep);
1505                 offset += (int)size;
1506                 di->call_data->flags = saved_flags;
1507         }
1509         return offset;
1512 static int
1513 drsuapi_dissect_DsGetNCChangesCompressedCtr(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_);
1515 static int
1516 drsuapi_dissect_element_DsGetNCChangesCtr7_level(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint32_t *level)
1518         offset = PIDL_dissect_uint32_val(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr7_level, 0, level);
1520         return offset;
1523 static int
1524 drsuapi_dissect_element_DsGetNCChangesCtr7_type(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint16_t *type)
1526         offset = drsuapi_dissect_enum_DsGetNCChangesCompressionType(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr7_type, type);
1528         return offset;
1531 static int
1532 drsuapi_dissect_element_DsGetNCChangesCtr7_ctr(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, uint32_t level _U_)
1534         offset = drsuapi_dissect_DsGetNCChangesCompressedCtr(tvb, offset, pinfo, tree, di, drep, hf_drsuapi_drsuapi_DsGetNCChangesCtr7_ctr, level);
1536         return offset;
1540 drsuapi_dissect_struct_DsGetNCChangesCtr7(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)
1542         uint32_t level = 0;
1543         uint16_t type = 0;
1544         uint32_t ctr_level = 0;
1545         proto_item *item = NULL;
1546         proto_tree *tree = NULL;
1547         int old_offset;
1549         ALIGN_TO_5_BYTES;
1551         old_offset = offset;
1553         if (parent_tree) {
1554                 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
1555                 tree = proto_item_add_subtree(item, ett_drsuapi_drsuapi_DsGetNCChangesCtr7);
1556         }
1558         offset = drsuapi_dissect_element_DsGetNCChangesCtr7_level(tvb, offset, pinfo, tree, di, drep, &level);
1560         offset = drsuapi_dissect_element_DsGetNCChangesCtr7_type(tvb, offset, pinfo, tree, di, drep, &type);
1562         ctr_level = (level & 0xFFFF) | (((uint32_t)type)<<16);
1564         offset = drsuapi_dissect_element_DsGetNCChangesCtr7_ctr(tvb, offset, pinfo, tree, di, drep, ctr_level);
1567         proto_item_set_len(item, offset-old_offset);
1570         if (di->call_data->flags & DCERPC_IS_NDR64) {
1571                 ALIGN_TO_5_BYTES;
1572         }
1574         return offset;
1577 static tvbuff_t *
1578 drsuapi_decompress_DsGetNCChangesXPRESS(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1580         tvbuff_t *completetvb = NULL;
1581         unsigned orig_length = tvb_reported_length_remaining(tvb, offset);
1582         unsigned remaining_length = orig_length;
1583         unsigned chunk_idx = 0;
1585         completetvb = tvb_new_composite();
1586         if (completetvb == NULL) {
1587                 return NULL;
1588         }
1590         while (remaining_length > 0) {
1591                 tvbuff_t *decomptvb = NULL;
1592                 uint32_t decomplen;
1593                 uint32_t complen;
1595                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, -1, &decomplen);
1596                 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, -1, &complen);
1598                 decomptvb = tvb_uncompress_lz77(tvb, offset, complen);
1599                 if (decomptvb == NULL) {
1600                         tvb_free_chain(completetvb);
1601                         return NULL;
1602                 }
1603                 offset += complen;
1605                 tvb_composite_append(completetvb, decomptvb);
1606                 chunk_idx += 1;
1608                 remaining_length = tvb_reported_length_remaining(tvb, offset);
1609         }
1611         tvb_composite_finalize(completetvb);
1612         proto_tree_add_text_internal(tree, completetvb, 0, tvb_reported_length(completetvb),
1613                                      "DRSUAPI LZ77 decompressed=%u",
1614                                      tvb_reported_length(completetvb));
1616         add_new_data_source(pinfo, completetvb, "DRSUAPI LZ77 decompressed");
1617         return completetvb;
1620 static void
1621 drsuapi_dissect_element_DsGetNCChangesXPRESSCtr6_ts__(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)
1623         tvbuff_t *decomptvb = NULL;
1625         decomptvb = drsuapi_decompress_DsGetNCChangesXPRESS(tvb, offset, pinfo, tree, di, drep);
1626         if (decomptvb == NULL) {
1627                 return;
1628         }
1630         drsuapi_dissect_struct_DsGetNCChangesCtr6TS(decomptvb,0,pinfo,tree,di,drep,hf_drsuapi_drsuapi_DsGetNCChangesXPRESSCtr6_ts,0);
1633 CODE END