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

librpc/ndr/ndr_sec_helper.c

index 4e721e16505142df8511092848a2bf89c61606d2..e07ee233599e4380d084e22c6447775dfa6d7808 100644 (file)
@@ -131,6 +131,24 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, ndr_flags
        return NDR_ERR_SUCCESS;
 }
 
+
+static inline enum ndr_err_code ndr_maybe_push_security_ace_object_ctr(struct ndr_push *ndr,
+                                                                      ndr_flags_type ndr_flags,
+                                                                      const struct security_ace *r)
+{
+       /*
+        * ndr_push_security_ace_object_ctr() does nothing (except tallocing
+        * and ndr_token fiddling) unless the ACE is an object ACE, which is
+        * usually very unlikely.
+        */
+       bool is_object = sec_ace_object(r->type);
+       if (is_object) {
+               NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, is_object));
+               NDR_CHECK(ndr_push_security_ace_object_ctr(ndr, ndr_flags, &r->object));
+       }
+       return NDR_ERR_SUCCESS;
+}
+
 _PUBLIC_ enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct security_ace *r)
 {
        NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
@@ -140,8 +158,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, ndr_flags
                NDR_CHECK(ndr_push_security_ace_flags(ndr, NDR_SCALARS, r->flags));
                NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, ndr_size_security_ace(r, ndr->flags)));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->access_mask));
-               NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, sec_ace_object(r->type)));
-               NDR_CHECK(ndr_push_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object));
+               NDR_CHECK(ndr_maybe_push_security_ace_object_ctr(ndr, NDR_SCALARS, r));
                NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, &r->trustee));
                if (sec_ace_has_extra_blob(r->type)) {
                        struct ndr_push *_ndr_coda;
@@ -153,8 +170,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, ndr_flags
                NDR_CHECK(ndr_push_trailer_align(ndr, 5));
        }
        if (ndr_flags & NDR_BUFFERS) {
-               NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, sec_ace_object(r->type)));
-               NDR_CHECK(ndr_push_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object));
+               NDR_CHECK(ndr_maybe_push_security_ace_object_ctr(ndr, NDR_BUFFERS, r));
        }
        return NDR_ERR_SUCCESS;
 }