From c4fc0b49f05f56174dc904a19d9e4dfc6d3ef523 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 12 Dec 2008 19:52:06 +0100 Subject: Manually marshall dom_sid, so we can use a fixed size array for dom_sid.sub_auths rather than a dynamically allocated one. This makes it possible to use the same DCE/RPC object code for Samba 3 and Samba 4's DCE/RPC parsers and allows copying sids more easily (since they no longer contain any pointers). The cost of having additional manual marshalling code is limited (~35 additional lines of C code). --- source4/librpc/idl/dom_sid.idl | 8 ++------ source4/librpc/ndr/ndr_dom_sid.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 8 deletions(-) (limited to 'source4/librpc') diff --git a/source4/librpc/idl/dom_sid.idl b/source4/librpc/idl/dom_sid.idl index 1fc8ee2165..40712fc371 100644 --- a/source4/librpc/idl/dom_sid.idl +++ b/source4/librpc/idl/dom_sid.idl @@ -22,13 +22,11 @@ cpp_quote("#define dom_sid0 dom_sid") ] interface dom_sid { - /* a domain SID. Note that unlike Samba3 this contains a pointer, - so you can't copy them using assignment */ - typedef [public,gensize,noprint,nosize] struct { + typedef [public,gensize,noprint,nosize,nopull,nopush] struct { uint8 sid_rev_num; /**< SID revision number */ [range(0,15)] int8 num_auths; /**< Number of sub-authorities */ uint8 id_auth[6]; /**< Identifier Authority */ - uint32 sub_auths[num_auths]; + uint32 sub_auths[15]; } dom_sid; /* id used to identify a endpoint, possibly in a cluster */ @@ -37,6 +35,4 @@ interface dom_sid uint32 id2; uint32 node; } server_id; - } - diff --git a/source4/librpc/ndr/ndr_dom_sid.c b/source4/librpc/ndr/ndr_dom_sid.c index b986231b4f..9b2118f56a 100644 --- a/source4/librpc/ndr/ndr_dom_sid.c +++ b/source4/librpc/ndr/ndr_dom_sid.c @@ -137,8 +137,7 @@ enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct /* handle a w2k bug which send random data in the buffer */ ZERO_STRUCTP(sid); } else if (sid->num_auths == 0 && sid->sub_auths) { - talloc_free(sid->sub_auths); - sid->sub_auths = NULL; + ZERO_STRUCT(sid->sub_auths); } return NDR_ERR_SUCCESS; @@ -215,3 +214,35 @@ enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, int ndr_flags, const s return ndr_push_dom_sid(ndr, ndr_flags, sid); } +_PUBLIC_ enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r) +{ + uint32_t cntr_sub_auths_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->sid_rev_num)); + NDR_CHECK(ndr_push_int8(ndr, NDR_SCALARS, r->num_auths)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6)); + for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sub_auths[cntr_sub_auths_0])); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dom_sid(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *r) +{ + uint32_t cntr_sub_auths_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num)); + NDR_CHECK(ndr_pull_int8(ndr, NDR_SCALARS, &r->num_auths)); + if (r->num_auths < 0 || r->num_auths > 15) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6)); + for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0])); + } + } + return NDR_ERR_SUCCESS; +} -- cgit