From f57cd1f63c900a7b17955cc7e11cd1f6b6b12474 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 27 Nov 2006 07:52:46 +0000 Subject: r19914: The "default" value with the name "" need different 0-length treatment as the other StringBufs, otherwise clicking on a key with this value being set leads to regedit.exe on w2k3 chew all memory. (This used to be commit b148cde7f39859102288a87b6f0bd2b250947a85) --- source3/librpc/gen_ndr/ndr_winreg.c | 83 ++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 6 deletions(-) (limited to 'source3/librpc/gen_ndr/ndr_winreg.c') diff --git a/source3/librpc/gen_ndr/ndr_winreg.c b/source3/librpc/gen_ndr/ndr_winreg.c index 811749d759..bc931dafe8 100644 --- a/source3/librpc/gen_ndr/ndr_winreg.c +++ b/source3/librpc/gen_ndr/ndr_winreg.c @@ -335,6 +335,77 @@ _PUBLIC_ void ndr_print_winreg_StringBuf(struct ndr_print *ndr, const char *name ndr->depth--; } +NTSTATUS ndr_push_winreg_ValNameBuf(struct ndr_push *ndr, int ndr_flags, const struct winreg_ValNameBuf *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, strlen_m_term(r->name)*2)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->size)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->name)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size/2)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen_m_term(r->name)*2/2)); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->name, strlen_m_term(r->name)*2/2, sizeof(uint16_t), CH_UTF16)); + } + } + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_winreg_ValNameBuf(struct ndr_pull *ndr, int ndr_flags, struct winreg_ValNameBuf *r) +{ + uint32_t _ptr_name; + TALLOC_CTX *_mem_save_name_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_name)); + if (_ptr_name) { + NDR_PULL_ALLOC(ndr, r->name); + } else { + r->name = NULL; + } + } + if (ndr_flags & NDR_BUFFERS) { + if (r->name) { + _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->name)); + if (ndr_get_array_length(ndr, &r->name) > ndr_get_array_size(ndr, &r->name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->name), ndr_get_array_length(ndr, &r->name)); + } + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->name, ndr_get_array_length(ndr, &r->name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, 0); + } + if (r->name) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->name, r->size/2)); + } + if (r->name) { + NDR_CHECK(ndr_check_array_length(ndr, (void*)&r->name, r->length/2)); + } + } + return NT_STATUS_OK; +} + +_PUBLIC_ void ndr_print_winreg_ValNameBuf(struct ndr_print *ndr, const char *name, const struct winreg_ValNameBuf *r) +{ + ndr_print_struct(ndr, name, "winreg_ValNameBuf"); + ndr->depth++; + ndr_print_uint16(ndr, "length", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?strlen_m_term(r->name)*2:r->length); + ndr_print_uint16(ndr, "size", r->size); + ndr_print_ptr(ndr, "name", r->name); + ndr->depth++; + if (r->name) { + ndr_print_string(ndr, "name", r->name); + } + ndr->depth--; + ndr->depth--; +} + NTSTATUS ndr_push_KeySecurityAttribute(struct ndr_push *ndr, int ndr_flags, const struct KeySecurityAttribute *r) { if (ndr_flags & NDR_SCALARS) { @@ -1394,7 +1465,7 @@ NTSTATUS ndr_push_winreg_EnumValue(struct ndr_push *ndr, int flags, const struct NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.enum_index)); if (r->in.name == NULL) return NT_STATUS_INVALID_PARAMETER_MIX; - NDR_CHECK(ndr_push_winreg_StringBuf(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name)); + NDR_CHECK(ndr_push_winreg_ValNameBuf(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.type)); if (r->in.type) { NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, *r->in.type)); @@ -1417,7 +1488,7 @@ NTSTATUS ndr_push_winreg_EnumValue(struct ndr_push *ndr, int flags, const struct } if (flags & NDR_OUT) { if (r->out.name == NULL) return NT_STATUS_INVALID_PARAMETER_MIX; - NDR_CHECK(ndr_push_winreg_StringBuf(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.name)); + NDR_CHECK(ndr_push_winreg_ValNameBuf(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.name)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.type)); if (r->out.type) { NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, *r->out.type)); @@ -1470,7 +1541,7 @@ NTSTATUS ndr_pull_winreg_EnumValue(struct ndr_pull *ndr, int flags, struct winre } _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_winreg_StringBuf(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name)); + NDR_CHECK(ndr_pull_winreg_ValNameBuf(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_type)); if (_ptr_type) { @@ -1543,7 +1614,7 @@ NTSTATUS ndr_pull_winreg_EnumValue(struct ndr_pull *ndr, int flags, struct winre } _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.name, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_winreg_StringBuf(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.name)); + NDR_CHECK(ndr_pull_winreg_ValNameBuf(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.name)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_type)); if (_ptr_type) { @@ -1629,7 +1700,7 @@ _PUBLIC_ void ndr_print_winreg_EnumValue(struct ndr_print *ndr, const char *name ndr_print_uint32(ndr, "enum_index", r->in.enum_index); ndr_print_ptr(ndr, "name", r->in.name); ndr->depth++; - ndr_print_winreg_StringBuf(ndr, "name", r->in.name); + ndr_print_winreg_ValNameBuf(ndr, "name", r->in.name); ndr->depth--; ndr_print_ptr(ndr, "type", r->in.type); ndr->depth++; @@ -1662,7 +1733,7 @@ _PUBLIC_ void ndr_print_winreg_EnumValue(struct ndr_print *ndr, const char *name ndr->depth++; ndr_print_ptr(ndr, "name", r->out.name); ndr->depth++; - ndr_print_winreg_StringBuf(ndr, "name", r->out.name); + ndr_print_winreg_ValNameBuf(ndr, "name", r->out.name); ndr->depth--; ndr_print_ptr(ndr, "type", r->out.type); ndr->depth++; -- cgit