From 7c81205557cdf97f9da960148e68699f89e86918 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 15 Jun 2004 06:56:34 +0000 Subject: r1152: Checkin of workarea. The parser can now dissect a big chunk of the samr operations. Security descriptors and unions are still left to do. (This used to be commit f29fb9a3fc3b9b36518c4bff49e9c030a8a921ba) --- source4/build/pidl/packet-dcerpc-eparser.c | 314 +++++++++++++++++++++++++++-- 1 file changed, 297 insertions(+), 17 deletions(-) (limited to 'source4/build/pidl/packet-dcerpc-eparser.c') diff --git a/source4/build/pidl/packet-dcerpc-eparser.c b/source4/build/pidl/packet-dcerpc-eparser.c index 5ae0a4a93e..11cc280831 100644 --- a/source4/build/pidl/packet-dcerpc-eparser.c +++ b/source4/build/pidl/packet-dcerpc-eparser.c @@ -6,6 +6,11 @@ #include "packet-dcerpc-nt.h" #include "packet-dcerpc-eparser.h" +static int hf_string4_len = -1; +static int hf_string4_offset = -1; +static int hf_string4_len2 = -1; +static int hf_string_data = -1; + /* Create a ndr_pull structure from data stored in a tvb at a given offset. */ struct e_ndr_pull *ndr_pull_init(tvbuff_t *tvb, int offset, packet_info *pinfo, @@ -20,6 +25,7 @@ struct e_ndr_pull *ndr_pull_init(tvbuff_t *tvb, int offset, packet_info *pinfo, ndr->pinfo = pinfo; ndr->tree = tree; ndr->drep = drep; + ndr->flags = NDR_SCALARS|NDR_BUFFERS; return ndr; } @@ -38,11 +44,11 @@ void ndr_pull_ptr(struct e_ndr_pull *e_ndr, int hf, guint32 *ptr) e_ndr->tree, e_ndr->drep, hf, ptr); } -void ndr_pull_level(struct e_ndr_pull *e_ndr, int hf, int *ptr) +void ndr_pull_level(struct e_ndr_pull *e_ndr, int hf, gint16 *data) { e_ndr->offset = dissect_ndr_uint16( e_ndr->tvb, e_ndr->offset, e_ndr->pinfo, - e_ndr->tree, e_ndr->drep, hf, ptr); + e_ndr->tree, e_ndr->drep, hf, data); } void ndr_pull_NTSTATUS(struct e_ndr_pull *e_ndr, int hf) @@ -52,49 +58,250 @@ void ndr_pull_NTSTATUS(struct e_ndr_pull *e_ndr, int hf) e_ndr->tree, e_ndr->drep, hf, NULL); } -void ndr_pull_uint8(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_uint8(struct e_ndr_pull *e_ndr, int hf, guint8 *data) { e_ndr->offset = dissect_ndr_uint8( e_ndr->tvb, e_ndr->offset, e_ndr->pinfo, - e_ndr->tree, e_ndr->drep, hf, NULL); + e_ndr->tree, e_ndr->drep, hf, data); } -void ndr_pull_uint16(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_uint16(struct e_ndr_pull *e_ndr, int hf, guint16 *data) { e_ndr->offset = dissect_ndr_uint16( e_ndr->tvb, e_ndr->offset, e_ndr->pinfo, - e_ndr->tree, e_ndr->drep, hf, NULL); + e_ndr->tree, e_ndr->drep, hf, data); } -void ndr_pull_uint32(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_uint32(struct e_ndr_pull *e_ndr, int hf, guint32 *data) { e_ndr->offset = dissect_ndr_uint32( e_ndr->tvb, e_ndr->offset, e_ndr->pinfo, - e_ndr->tree, e_ndr->drep, hf, NULL); + e_ndr->tree, e_ndr->drep, hf, data); } -void ndr_pull_int64(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_int64(struct e_ndr_pull *e_ndr, int hf, gint64 *data) { } -void ndr_pull_uint64(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_uint64(struct e_ndr_pull *e_ndr, int hf, guint64 *data) { } -void ndr_pull_string(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_string(struct e_ndr_pull *ndr, int ndr_flags) { + guint32 len1, ofs, len2; + char *data; + + if (!(ndr_flags & NDR_SCALARS)) { + return; + } + + switch (ndr->flags & LIBNDR_STRING_FLAGS) { + case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: + case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: + + ndr_pull_uint32(ndr, hf_string4_len, &len1); + ndr_pull_uint32(ndr, hf_string4_offset, &ofs); + ndr_pull_uint32(ndr, hf_string4_len2, &len2); + + if (len2 > 65535) + return; + + data = g_malloc(len2*2); + + proto_tree_add_bytes(ndr->tree, hf_string_data, ndr->tvb, + ndr->offset, len2 * 2, data); + + g_free(data); + + ndr->offset += len2 * 2; + +#if 0 + + ndr_pull_uint32(ndr, &len1)); + ndr_pull_uint32(ndr, &ofs); + ndr_pull_uint32(ndr, &len2); + if (len2 > len1) { + return ndr_pull_error(ndr, NDR_ERR_STRING, + "Bad string lengths len1=%u ofs=%u len2=%u\n", + len1, ofs, len2); + } + if (len2 == 0) { + *s = talloc_strdup(ndr->mem_ctx, ""); + break; + } + NDR_PULL_NEED_BYTES(ndr, len2*2); + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, + ndr->data+ndr->offset, + len2*2, + (const void **)&as); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr_pull_advance(ndr, len2*2); + + /* this is a way of detecting if a string is sent with the wrong + termination */ + if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) { + if (strlen(as) < len2) { + DEBUG(6,("short string '%s'\n", as)); + } + } else { + if (strlen(as) == len2) { + DEBUG(6,("long string '%s'\n", as)); + } + } + *s = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_SIZE4: + +#if 0 + + ndr_pull_uint32(ndr, &len1); + NDR_PULL_NEED_BYTES(ndr, len1*2); + if (len1 == 0) { + *s = talloc_strdup(ndr->mem_ctx, ""); + break; + } + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, + ndr->data+ndr->offset, + len1*2, + (const void **)&as); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr_pull_advance(ndr, len1*2); + *s = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_NULLTERM: + +#if 0 + + len1 = strnlen_w(ndr->data+ndr->offset, + (ndr->data_size - ndr->offset)/2); + if (len1*2+2 <= ndr->data_size - ndr->offset) { + len1++; + } + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, + ndr->data+ndr->offset, + len1*2, + (const void **)s); + if (ret == -1) { + return ndr_pull_error(ndr, NDR_ERR_CHARCNV, + "Bad character conversion"); + } + ndr_pull_advance(ndr, len1*2); + +#endif + + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: + +#if 0 + + ndr_pull_uint32(ndr, &len1); + ndr_pull_uint32(ndr, &ofs); + ndr_pull_uint32(ndr, &len2); + if (len2 > len1) { + return ndr_pull_error(ndr, NDR_ERR_STRING, + "Bad ascii string lengths len1=%u ofs=%u len2=%u\n", + len1, ofs, len2); + } + NDR_ALLOC_N(ndr, as, (len2+1)); + ndr_pull_bytes(ndr, as, len2); + as[len2] = 0; + (*s) = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4: + +#if 0 + ndr_pull_uint32(ndr, &ofs); + ndr_pull_uint32(ndr, &len2); + NDR_ALLOC_N(ndr, as, (len2+1)); + ndr_pull_bytes(ndr, as, len2); + as[len2] = 0; + (*s) = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2: + +#if 0 + + ndr_pull_uint16(ndr, &len3); + NDR_ALLOC_N(ndr, as, (len3+1)); + ndr_pull_bytes(ndr, as, len3); + as[len3] = 0; + (*s) = as; + +#endif + + break; + + case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM: + +#if 0 + + len1 = strnlen(ndr->data+ndr->offset, (ndr->data_size - ndr->offset)); + if (len1+1 <= ndr->data_size - ndr->offset) { + len1++; + } + NDR_ALLOC_N(ndr, as, (len1+1)); + ndr_pull_bytes(ndr, as, len1); + as[len1] = 0; + (*s) = as; + +#endif + + break; + + default: + +#if 0 + + return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n", + ndr->flags & LIBNDR_STRING_FLAGS); + +#endif + + } } -void ndr_pull_NTTIME(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_NTTIME(struct e_ndr_pull *e_ndr, int hf, gNTTIME *data) { } -void ndr_pull_HYPER_T(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_HYPER_T(struct e_ndr_pull *e_ndr, int hf, gHYPER_T *data) { } -void ndr_pull_dom_sid2(struct e_ndr_pull *e_ndr, int hf) +void ndr_pull_dom_sid2(struct e_ndr_pull *e_ndr, int flags) { + guint32 num_auths; + if (!(flags & NDR_SCALARS)) { + return; + } + ndr_pull_uint32(e_ndr, hf_string4_len, &num_auths); + + ndr_pull_dom_sid(e_ndr, flags); } #if 0 @@ -156,18 +363,91 @@ void ndr_pull_struct_start(struct e_ndr_pull *ndr) */ void ndr_pull_struct_end(struct e_ndr_pull *ndr) { - struct ndr_ofs_list *ofs = ndr->ofs_list->next; - g_free(ndr->ofs_list); - ndr->ofs_list = ofs; + ndr->ofs_list = ndr->ofs_list->next; } void ndr_pull_subcontext_header(struct e_ndr_pull *ndr, size_t sub_size, struct e_ndr_pull *ndr2) { + ndr2->tvb = ndr->tvb; + ndr2->offset = ndr->offset; + ndr2->pinfo = ndr->pinfo; + ndr2->tree = ndr->tree; + ndr2->drep = ndr->drep; + ndr2->ofs_list = ndr->ofs_list; + ndr2->flags = ndr->flags; } void ndr_pull_relative(struct e_ndr_pull *ndr, void (*fn)(struct e_ndr_pull *, int ndr_flags)) { } + +int lsa_dissect_LSA_SECURITY_DESCRIPTOR(tvbuff_t tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + return offset; +} + +int lsa_dissect_LSA_SECURITY_DESCRIPTOR_data(tvbuff_t tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + return offset; +} + +int lsa_dissect_POLICY_DNS_DOMAIN_INFO(tvbuff_t tvb, int offset, + packet_info *pinfo, proto_tree *tree, + guint8 *drep) +{ + return offset; +} + +void ndr_pull_bytes(struct e_ndr_pull *ndr, guint32 n) +{ + ndr->offset += n; +} + +void ndr_pull_array_uint8(struct e_ndr_pull *ndr, int hf, int ndr_flags, guint32 n) +{ + guint32 i; + if (!(ndr_flags & NDR_SCALARS)) { + return; + } + for (i=0;i