diff options
author | Stefan Metzmacher <metze@samba.org> | 2013-02-06 16:44:12 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2016-07-20 21:27:18 +0200 |
commit | 8e458360b454a10bd6fea0bd76c995311348bf11 (patch) | |
tree | f2b74d2b08df49bd1063af366f6e66ce9cdd2070 | |
parent | 4f5dde6730a7074ce36be59889cd181ddc79193f (diff) | |
download | samba-8e458360b454a10bd6fea0bd76c995311348bf11.tar.gz |
krb5pac: fix push/pull of subcontexts in PAC_BUFFER
We need to have two subcontexts to get the padding right,
the outer subcontext uses NDR_ROUND(_ndr_size, 8), while
the inner subcontext only uses _ndr_size.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
-rw-r--r-- | librpc/idl/krb5pac.idl | 9 | ||||
-rw-r--r-- | librpc/ndr/ndr_krb5pac.c | 21 |
2 files changed, 19 insertions, 11 deletions
diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl index ed67bd11151..53d554d1bf0 100644 --- a/librpc/idl/krb5pac.idl +++ b/librpc/idl/krb5pac.idl @@ -133,7 +133,14 @@ interface krb5pac typedef [public,nopush,nopull] struct { PAC_TYPE type; [value(_ndr_size_PAC_INFO(info, type, 0))] uint32 _ndr_size; - [relative,switch_is(type),subcontext(0),subcontext_size(_subcontext_size_PAC_INFO(r, ndr->flags)),flag(NDR_ALIGN8)] PAC_INFO *info; + /* + * We need to have two subcontexts to get the padding right, + * the outer subcontext uses NDR_ROUND(_ndr_size, 8), while + * the inner subcontext only uses _ndr_size. + * + * We do that in non-generated push/pull functions. + */ + [relative,switch_is(type),subcontext(0),subcontext_size(NDR_ROUND(_ndr_size,8)),flag(NDR_ALIGN8)] PAC_INFO *info; [value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */ } PAC_BUFFER; diff --git a/librpc/ndr/ndr_krb5pac.c b/librpc/ndr/ndr_krb5pac.c index fcbc1f377d0..a0358c91a85 100644 --- a/librpc/ndr/ndr_krb5pac.c +++ b/librpc/ndr/ndr_krb5pac.c @@ -34,12 +34,6 @@ size_t _ndr_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) } } -static size_t _subcontext_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) -{ - size_t s = ndr_size_PAC_INFO(r, level, flags); - return NDR_ROUND(s,8); -} - enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER *r) { if (ndr_flags & NDR_SCALARS) { @@ -61,11 +55,15 @@ enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const if (r->info) { NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->info)); { + struct ndr_push *_ndr_info_pad; struct ndr_push *_ndr_info; - NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0))); + size_t _ndr_size = _ndr_size_PAC_INFO(r->info, r->type, 0); + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info_pad, 0, NDR_ROUND(_ndr_size, 8))); + NDR_CHECK(ndr_push_subcontext_start(_ndr_info_pad, &_ndr_info, 0, _ndr_size)); NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type)); NDR_CHECK(ndr_push_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info)); - NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0))); + NDR_CHECK(ndr_push_subcontext_end(_ndr_info_pad, _ndr_info, 0, _ndr_size)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info_pad, 0, NDR_ROUND(_ndr_size, 8))); } NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->info)); } @@ -108,11 +106,14 @@ enum ndr_err_code ndr_pull_PAC_BUFFER(struct ndr_pull *ndr, int ndr_flags, struc _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->info, 0); { + struct ndr_pull *_ndr_info_pad; struct ndr_pull *_ndr_info; - NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 0, r->_ndr_size)); + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info_pad, 0, NDR_ROUND(r->_ndr_size, 8))); + NDR_CHECK(ndr_pull_subcontext_start(_ndr_info_pad, &_ndr_info, 0, r->_ndr_size)); NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->info, r->type)); NDR_CHECK(ndr_pull_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info)); - NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 0, r->_ndr_size)); + NDR_CHECK(ndr_pull_subcontext_end(_ndr_info_pad, _ndr_info, 0, r->_ndr_size)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info_pad, 0, NDR_ROUND(r->_ndr_size, 8))); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); if (ndr->offset > ndr->relative_highest_offset) { |