The branch, master has been updated via bf1fa9e negoex.idl: use DATA_BLOB for negoex_BYTE_VECTOR via a4fa489 negoex.idl: initial version from d7feb18 s3: libsmb: Correctly initialize the list head when keeping a list of primary followed by DFS connections.
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit bf1fa9e080c48ce02d2a83b1095854485d00d5f0 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Dec 7 09:31:03 2015 +0100 negoex.idl: use DATA_BLOB for negoex_BYTE_VECTOR That's much easier for the callers. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Fri Dec 18 04:07:56 CET 2015 on sn-devel-144 commit a4fa4897058e32c81e3c1cac3cb321757a967ebc Author: Stefan Metzmacher <me...@samba.org> Date: Mon Dec 7 09:30:47 2015 +0100 negoex.idl: initial version Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> ----------------------------------------------------------------------- Summary of changes: librpc/idl/negoex.idl | 156 ++++++++++++++ librpc/idl/wscript_build | 2 +- librpc/ndr/ndr_negoex.c | 520 +++++++++++++++++++++++++++++++++++++++++++++++ librpc/ndr/ndr_negoex.h | 37 ++++ librpc/wscript_build | 7 +- 5 files changed, 720 insertions(+), 2 deletions(-) create mode 100644 librpc/idl/negoex.idl create mode 100644 librpc/ndr/ndr_negoex.c create mode 100644 librpc/ndr/ndr_negoex.h Changeset truncated at 500 lines: diff --git a/librpc/idl/negoex.idl b/librpc/idl/negoex.idl new file mode 100644 index 0000000..e2f8222 --- /dev/null +++ b/librpc/idl/negoex.idl @@ -0,0 +1,156 @@ +#include "idl_types.h" + +/* + NEGOEX interface definition + See http://ietfreport.isoc.org/all-ids/draft-zhu-negoex-04.txt +*/ + +import "misc.idl"; + +[ + uuid("fcc30ddc-98d0-11e5-8a56-83e9a6706f2f"), + helper("../librpc/ndr/ndr_negoex.h"), + helpstring("NEGOEX messages") +] +interface negoex +{ + typedef [nopush,nopull,noprint] struct { +#if 0 + [relative,size_is(length)] uint8 *data; + uint32 length; +#else + DATA_BLOB blob; + /* + * internal helper variable */ + uint32 _length; + /* + * the dummy pointer is needed in order to let the + * callers use NDR_BUFFERS + */ + [relative] uint8 *_dummy; +#endif + } negoex_BYTE_VECTOR; + + typedef [public] struct { + GUID guid; + } negoex_AUTH_SCHEME; + + typedef [nopush,nopull] struct { + [relative,size_is(count)] negoex_AUTH_SCHEME *array; + uint32 count; + } negoex_AUTH_SCHEME_VECTOR; + + typedef [v1_enum] enum { + NEGOEX_EXTENSION_TYPE_TODO = 0 /* TODO */ + } negoex_ExtensionTypes; + + typedef [public] struct { + negoex_ExtensionTypes type; + negoex_BYTE_VECTOR value; + } negoex_EXTENSION; + + typedef [nopush,nopull] struct { + [relative,size_is(count)] negoex_EXTENSION *array; + uint32 count; + } negoex_EXTENSION_VECTOR; + + typedef [v1_enum] enum { + NEGOEX_CHECKSUM_SCHEME_RFC3961 = 1 + } negoex_ChecksumSchemes; + + typedef struct { + [value(20)] uint32 header_length; + negoex_ChecksumSchemes scheme; + uint32 type; + negoex_BYTE_VECTOR value; + } negoex_CHECKSUM; + + typedef [v1_enum] enum { + NEGOEX_ALERT_VERIFY_NO_KEY = 1 + } negoex_AlertReason; + + typedef [public] struct { + [value(4)] uint32 header_length; /* TODO: is 4 correct? */ + negoex_AlertReason reason; + } negoex_ALERT_PULSE; + + typedef [v1_enum] enum { + NEGOEX_ALERT_TYPE_PULSE = 1 + } negoex_AlertTypes; + + typedef [public] struct { + negoex_AlertTypes type; + negoex_BYTE_VECTOR value; + } negoex_ALERT; + + typedef [nopush,nopull] struct { + [relative,size_is(count)] negoex_ALERT *array; + uint32 count; + } negoex_ALERT_VECTOR; + + typedef [public,v1_enum] enum { + NEGOEX_MESSAGE_TYPE_INITIATOR_NEGO = 0, + NEGOEX_MESSAGE_TYPE_ACCEPTOR_NEGO = 1, + NEGOEX_MESSAGE_TYPE_INITIATOR_META_DATA = 2, + NEGOEX_MESSAGE_TYPE_ACCEPTOR_META_DATA = 3, + NEGOEX_MESSAGE_TYPE_CHALLENGE = 4, + NEGOEX_MESSAGE_TYPE_AP_REQUEST = 5, + NEGOEX_MESSAGE_TYPE_VERIFY = 6, + NEGOEX_MESSAGE_TYPE_ALERT = 7 + } negoex_MESSAGE_TYPE; + + const uint32 NEGOEX_PROTOCOL_VERSION_0 = 0; + + typedef [flag(NDR_PAHEX)] struct { + [flag(NDR_PAHEX)] uint8 random[32]; + [value(NEGOEX_PROTOCOL_VERSION_0)] udlong protocol_version; + negoex_AUTH_SCHEME_VECTOR auth_schemes; + negoex_EXTENSION_VECTOR extensions; + } negoex_NEGO_PAYLOAD; + + typedef struct { + negoex_AUTH_SCHEME auth_scheme; + negoex_BYTE_VECTOR exchange; + } negoex_EXCHANGE_PAYLOAD; + + typedef struct { + negoex_AUTH_SCHEME auth_scheme; + negoex_CHECKSUM checksum; + } negoex_VERIFY_PAYLOAD; + + typedef struct { + negoex_AUTH_SCHEME auth_scheme; + NTSTATUS status; + negoex_ALERT_VECTOR alerts; + } negoex_ALERT_PAYLOAD; + + typedef [public,nodiscriminant] union { + [case(NEGOEX_MESSAGE_TYPE_INITIATOR_NEGO)] negoex_NEGO_PAYLOAD nego; + [case(NEGOEX_MESSAGE_TYPE_ACCEPTOR_NEGO)] negoex_NEGO_PAYLOAD nego; + [case(NEGOEX_MESSAGE_TYPE_INITIATOR_META_DATA)] negoex_EXCHANGE_PAYLOAD exchange; + [case(NEGOEX_MESSAGE_TYPE_ACCEPTOR_META_DATA)] negoex_EXCHANGE_PAYLOAD exchange; + [case(NEGOEX_MESSAGE_TYPE_CHALLENGE)] negoex_EXCHANGE_PAYLOAD exchange; + [case(NEGOEX_MESSAGE_TYPE_AP_REQUEST)] negoex_EXCHANGE_PAYLOAD exchange; + [case(NEGOEX_MESSAGE_TYPE_VERIFY)] negoex_VERIFY_PAYLOAD verify; + [case(NEGOEX_MESSAGE_TYPE_ALERT)] negoex_ALERT_PAYLOAD alert; + } negoex_PAYLOAD; + + typedef [public,relative_base,gensize,nopull] struct { + [charset(DOS),value("NEGOEXTS")] uint8 signature[8]; + negoex_MESSAGE_TYPE type; + uint32 sequence_number; + [value(ndr_negoex_MESSAGE_header_length(r))] uint32 header_length; + [value(ndr_size_negoex_MESSAGE(r, ndr->flags))] uint32 message_length; + GUID conversation_id; + [switch_is(type)] negoex_PAYLOAD p; + } negoex_MESSAGE; + + typedef [public,nopush,nopull,flag(NDR_NOALIGN)] struct { + uint32 count; + negoex_MESSAGE messages[count]; + } negoex_MESSAGE_ARRAY; + + void decode_negoex_MESSAGE( + [in] negoex_MESSAGE_ARRAY array + ); +} diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build index 6316edd..47acc0d 100644 --- a/librpc/idl/wscript_build +++ b/librpc/idl/wscript_build @@ -2,7 +2,7 @@ bld.SAMBA_PIDL_LIST('PIDL', '''atsvc.idl auth.idl drsuapi.idl epmapper.idl initshutdown.idl - misc.idl ntlmssp.idl schannel.idl trkwks.idl + misc.idl ntlmssp.idl negoex.idl schannel.idl trkwks.idl audiosrv.idl dfsblobs.idl dsbackup.idl eventlog.idl file_id.idl keysvc.idl msgsvc.idl ntsvcs.idl remact.idl security.idl smb_acl.idl unixinfo.idl wzcsvc.idl browser.idl dfs.idl dssetup.idl frsapi.idl krb5pac.idl diff --git a/librpc/ndr/ndr_negoex.c b/librpc/ndr/ndr_negoex.c new file mode 100644 index 0000000..b5cb5bc --- /dev/null +++ b/librpc/ndr/ndr_negoex.c @@ -0,0 +1,520 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling special NEGOEX structures + + Copyright (C) Stefan Metzmacher 2015 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include "includes.h" +#include "librpc/gen_ndr/ndr_negoex.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/ndr/ndr_negoex.h" + +void ndr_print_negoex_BYTE_VECTOR(struct ndr_print *ndr, const char *name, const struct negoex_BYTE_VECTOR *r) +{ + ndr_print_struct(ndr, name, "negoex_BYTE_VECTOR"); + if (r == NULL) { ndr_print_null(ndr); return; } + ndr->depth++; + ndr_print_DATA_BLOB(ndr, "blob", r->blob); + ndr->depth--; +} + +enum ndr_err_code ndr_push_negoex_BYTE_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_BYTE_VECTOR *r) +{ + NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 5)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->blob.data)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->blob.length)); + NDR_CHECK(ndr_push_trailer_align(ndr, 5)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->blob.data) { + NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->blob.data)); +#if 0 + NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->blob.length)); +#endif + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->blob.data, r->blob.length)); + NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->blob.data)); + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_negoex_BYTE_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_BYTE_VECTOR *r) +{ + uint32_t _ptr_data; + uint32_t size_data_1 = 0; + TALLOC_CTX *_mem_save_data_0 = NULL; + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + r->_dummy = NULL; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 5)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data)); + if (_ptr_data) { + NDR_PULL_ALLOC(ndr, r->blob.data); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->blob.data, _ptr_data)); + } else { + r->blob.data = NULL; + } + r->blob.length = 0; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &size_data_1)); + r->_length = size_data_1; + NDR_CHECK(ndr_pull_trailer_align(ndr, 5)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->blob.data) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->blob.data)); + _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->blob.data, 0); +#if 0 + NDR_CHECK(ndr_pull_array_size(ndr, &r->blob.data)); + size_data_1 = ndr_get_array_size(ndr, &r->blob.data); +#else + size_data_1 = r->_length; +#endif + NDR_PULL_ALLOC_N(ndr, r->blob.data, size_data_1); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->blob.data, size_data_1)); + r->blob.length = size_data_1; + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, 0); + if (ndr->offset > ndr->relative_highest_offset) { + ndr->relative_highest_offset = ndr->offset; + } + ndr->offset = _relative_save_offset; + } +#if 0 + if (r->blob.data) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->blob.data, r->blob.length)); + } +#endif + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_negoex_AUTH_SCHEME_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_AUTH_SCHEME_VECTOR *r) +{ + uint32_t cntr_array_1; + NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 5)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); + NDR_CHECK(ndr_push_trailer_align(ndr, 5)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->array) { + NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array)); +#if 0 + NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count)); +#endif + for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) { + NDR_CHECK(ndr_push_negoex_AUTH_SCHEME(ndr, NDR_SCALARS, &r->array[cntr_array_1])); + } + NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array)); + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_negoex_AUTH_SCHEME_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_AUTH_SCHEME_VECTOR *r) +{ + uint32_t _ptr_array; + uint32_t size_array_1 = 0; + uint32_t cntr_array_1; + TALLOC_CTX *_mem_save_array_0 = NULL; + TALLOC_CTX *_mem_save_array_1 = NULL; + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 5)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array)); + if (_ptr_array) { + NDR_PULL_ALLOC(ndr, r->array); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array)); + } else { + r->array = NULL; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); + NDR_CHECK(ndr_pull_trailer_align(ndr, 5)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->array) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->array)); + _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); +#if 0 + NDR_CHECK(ndr_pull_array_size(ndr, &r->array)); + size_array_1 = ndr_get_array_size(ndr, &r->array); +#else + size_array_1 = r->count; +#endif + NDR_PULL_ALLOC_N(ndr, r->array, size_array_1); + _mem_save_array_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); + for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) { + NDR_CHECK(ndr_pull_negoex_AUTH_SCHEME(ndr, NDR_SCALARS, &r->array[cntr_array_1])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_1, 0); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0); + if (ndr->offset > ndr->relative_highest_offset) { + ndr->relative_highest_offset = ndr->offset; + } + ndr->offset = _relative_save_offset; + } +#if 0 + if (r->array) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count)); + } +#endif + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_negoex_EXTENSION_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_EXTENSION_VECTOR *r) +{ + uint32_t cntr_array_1; + NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 5)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); + NDR_CHECK(ndr_push_trailer_align(ndr, 5)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->array) { + NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array)); +#if 0 + NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count)); +#endif + for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) { + NDR_CHECK(ndr_push_negoex_EXTENSION(ndr, NDR_SCALARS, &r->array[cntr_array_1])); + } + for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) { + NDR_CHECK(ndr_push_negoex_EXTENSION(ndr, NDR_BUFFERS, &r->array[cntr_array_1])); + } + NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array)); + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_negoex_EXTENSION_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_EXTENSION_VECTOR *r) +{ + uint32_t _ptr_array; + uint32_t size_array_1 = 0; + uint32_t cntr_array_1; + TALLOC_CTX *_mem_save_array_0 = NULL; + TALLOC_CTX *_mem_save_array_1 = NULL; + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 5)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array)); + if (_ptr_array) { + NDR_PULL_ALLOC(ndr, r->array); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array)); + } else { + r->array = NULL; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); + NDR_CHECK(ndr_pull_trailer_align(ndr, 5)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->array) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->array)); + _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); +#if 0 + NDR_CHECK(ndr_pull_array_size(ndr, &r->array)); + size_array_1 = ndr_get_array_size(ndr, &r->array); +#else + size_array_1 = r->count; +#endif + NDR_PULL_ALLOC_N(ndr, r->array, size_array_1); + _mem_save_array_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); + for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) { + NDR_CHECK(ndr_pull_negoex_EXTENSION(ndr, NDR_SCALARS, &r->array[cntr_array_1])); + } + for (cntr_array_1 = 0; cntr_array_1 < (size_array_1); cntr_array_1++) { + NDR_CHECK(ndr_pull_negoex_EXTENSION(ndr, NDR_BUFFERS, &r->array[cntr_array_1])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_1, 0); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0); + if (ndr->offset > ndr->relative_highest_offset) { + ndr->relative_highest_offset = ndr->offset; + } + ndr->offset = _relative_save_offset; + } +#if 0 + if (r->array) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count)); + } +#endif + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_negoex_ALERT_VECTOR(struct ndr_push *ndr, int ndr_flags, const struct negoex_ALERT_VECTOR *r) +{ + uint32_t cntr_array_1; + NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 5)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->array)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); + NDR_CHECK(ndr_push_trailer_align(ndr, 5)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->array) { + NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->array)); +#if 0 + NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->count)); +#endif + for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) { + NDR_CHECK(ndr_push_negoex_ALERT(ndr, NDR_SCALARS, &r->array[cntr_array_1])); + } + for (cntr_array_1 = 0; cntr_array_1 < (r->count); cntr_array_1++) { + NDR_CHECK(ndr_push_negoex_ALERT(ndr, NDR_BUFFERS, &r->array[cntr_array_1])); + } + NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->array)); + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_negoex_ALERT_VECTOR(struct ndr_pull *ndr, int ndr_flags, struct negoex_ALERT_VECTOR *r) +{ + uint32_t _ptr_array; + uint32_t size_array_1 = 0; + uint32_t cntr_array_1; + TALLOC_CTX *_mem_save_array_0 = NULL; + TALLOC_CTX *_mem_save_array_1 = NULL; + NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 5)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array)); + if (_ptr_array) { + NDR_PULL_ALLOC(ndr, r->array); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->array, _ptr_array)); + } else { + r->array = NULL; + } -- Samba Shared Repository