From 276e67fe174caab58d9a020a9357ca0d04631f13 Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Mon, 1 Jan 2024 10:21:33 +1300 Subject: [PATCH] ndr: avoid object ACE pull overhead for non-object ACE When an ACE is not an object ACE, which is common, setting the switch value and attempting the object ACE GUID pull is just going to do nothing, and we know that ahead of time. By noticing that we can save a bit of time on a common operation. Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett BUG: https://bugzilla.samba.org/show_bug.cgi?id=15574 (cherry picked from commit fce4d51eb492a6fc807c6849cd4bd65ca7714509) --- librpc/ndr/ndr_sec_helper.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/librpc/ndr/ndr_sec_helper.c b/librpc/ndr/ndr_sec_helper.c index 98663a12ad9..4e721e16505 100644 --- a/librpc/ndr/ndr_sec_helper.c +++ b/librpc/ndr/ndr_sec_helper.c @@ -79,6 +79,27 @@ size_t ndr_size_security_ace(const struct security_ace *ace, libndr_flags flags) return ret; } + +static inline enum ndr_err_code ndr_maybe_pull_security_ace_object_ctr(struct ndr_pull *ndr, + ndr_flags_type ndr_flags, + struct security_ace *r) +{ + /* + * If this is not an object ACE (as is usually common), + * ndr_pull_security_ace_object_ctr() will do nothing. + * + * By avoiding calling the function in that case, we avoid some + * tallocing and ndr token busywork. + */ + bool is_object = sec_ace_object(r->type); + if (is_object) { + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, is_object)); + NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, ndr_flags, &r->object)); + } + return NDR_ERR_SUCCESS; +} + + _PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct security_ace *r) { NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); @@ -89,8 +110,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, ndr_flags NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask)); - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, sec_ace_object(r->type))); - NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object)); + NDR_CHECK(ndr_maybe_pull_security_ace_object_ctr(ndr, NDR_SCALARS, r)); NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee)); sub_size = ndr_subcontext_size_of_ace_coda(r, r->size, ndr->flags); if (sub_size == 0) { @@ -106,8 +126,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, ndr_flags NDR_CHECK(ndr_pull_trailer_align(ndr, 5)); } if (ndr_flags & NDR_BUFFERS) { - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, sec_ace_object(r->type))); - NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object)); + NDR_CHECK(ndr_maybe_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, r)); } return NDR_ERR_SUCCESS; } -- 2.47.3