ndr: short-circuit ace coda if no bytes left
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Sun, 31 Dec 2023 00:06:40 +0000 (13:06 +1300)
committerJule Anger <janger@samba.org>
Mon, 12 Feb 2024 10:53:13 +0000 (10:53 +0000)
The overwhelmingly common case is that there are no bytes left, and
regardless of the ACE type we want to store an empty blob.

We know the blob will be empty if there are no bytes, so we don't need
to allocate a sub-ndr and tokens list and so forth.

This can save almost half the time of a security descriptor pull.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15574
(cherry picked from commit ac0c8ee01ea624e9c486251da2132710c2a43ddc)

librpc/ndr/ndr_sec_helper.c

index a634dfd75fc72a09087195c9abac2f61d9d7eb69..6ae177f292d5e59dbf113114fde5fc32e7a14f52 100644 (file)
@@ -79,6 +79,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, ndr_flags
 {
        NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
        if (ndr_flags & NDR_SCALARS) {
+               ssize_t sub_size;
                NDR_CHECK(ndr_pull_align(ndr, 5));
                NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type));
                NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags));
@@ -87,9 +88,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, ndr_flags
                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_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) {
+                       r->coda.ignored.data = NULL;
+                       r->coda.ignored.length = 0;
+               } else {
                        struct ndr_pull *_ndr_coda;
-                       ssize_t sub_size = ndr_subcontext_size_of_ace_coda(r, r->size, ndr->flags);
                        NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_coda, 0, sub_size));
                        NDR_CHECK(ndr_pull_set_switch_value(_ndr_coda, &r->coda, r->type));
                        NDR_CHECK(ndr_pull_security_ace_coda(_ndr_coda, NDR_SCALARS|NDR_BUFFERS, &r->coda));