ndr: avoid object ACE pull overhead for non-object ACE
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Sun, 31 Dec 2023 21:21:33 +0000 (10:21 +1300)
committerJule Anger <janger@samba.org>
Mon, 12 Feb 2024 10:53:13 +0000 (10:53 +0000)
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 <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 fce4d51eb492a6fc807c6849cd4bd65ca7714509)

librpc/ndr/ndr_sec_helper.c

index 98663a12ad9e43f957083211a5d458ef98308540..4e721e16505142df8511092848a2bf89c61606d2 100644 (file)
@@ -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;
 }