]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
conditional_aces: Avoid manual parsing for ace_condition_bytes, use DATA_BLOB
authorAndrew Bartlett <abartlet@samba.org>
Thu, 21 Sep 2023 00:55:53 +0000 (12:55 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 26 Sep 2023 23:45:36 +0000 (23:45 +0000)
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
lib/util/data_blob.c
libcli/security/claims-conversions.c
libcli/security/conditional_ace.c
libcli/security/sddl_conditional_ace.c
librpc/idl/conditional_ace.idl

index 677f7c192111ffa71f3353b89abb36f028f8c996..69a340c6fb8d9613f321c0eab229f4eca7b2b7d1 100644 (file)
@@ -125,6 +125,7 @@ _PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2)
        }
        ret = memcmp(d1->data, d2->data, MIN(d1->length, d2->length));
        if (ret == 0) {
+               /* Note this ordering is used in conditional aces */
                return d1->length - d2->length;
        }
        return ret;
index 176d23567d6dbed3c3531b47058af1fc61ce6fd4..9bb09c013602d3c3e475f046aa0253ca6961cde9 100644 (file)
@@ -89,7 +89,7 @@ static bool claim_v1_octet_string_to_ace_octet_string(
        struct ace_condition_token *result)
 {
        DATA_BLOB *v = NULL;
-       struct ace_condition_bytes w = {0};
+       DATA_BLOB w = data_blob_null;
 
        v = claim->values[offset].octet_value;
 
@@ -99,16 +99,11 @@ static bool claim_v1_octet_string_to_ace_octet_string(
                            v->length, CONDITIONAL_ACE_MAX_LENGTH);
                return false;
        }
-       if (v->length == 0) {
-               w.bytes = NULL;
-               w.length = 0;
-       } else {
-               w.bytes = talloc_memdup(mem_ctx, v->data, v->length);
-               if (w.bytes == NULL) {
+       if (v->length != 0) {
+               w = data_blob_talloc(mem_ctx, v->data, v->length);
+               if (w.data == NULL) {
                        return false;
                }
-
-               w.length = v->length;
        }
 
        result->type = CONDITIONAL_ACE_TOKEN_OCTET_STRING;
@@ -396,7 +391,7 @@ static bool ace_octet_string_to_claim_v1_octet_string(
        }
 
        *v = data_blob_talloc(mem_ctx,
-                             tok->data.bytes.bytes,
+                             tok->data.bytes.data,
                              tok->data.bytes.length);
        if (v->data == NULL) {
                return false;
index 569bdd82696dbd4d6c2508f26369f011f7285b9e..2957dc20319d17c19f465506cb61918d78995837 100644 (file)
@@ -26,6 +26,7 @@
 #include "lib/util/tsort.h"
 #include "lib/util/debug.h"
 #include "lib/util/bytearray.h"
+#include "lib/util/talloc_stack.h"
 #include "util/discard.h"
 
 /*
@@ -230,37 +231,53 @@ static ssize_t push_unicode(uint8_t *data, size_t length,
 
 static ssize_t pull_bytes(TALLOC_CTX *mem_ctx,
                          uint8_t *data, size_t length,
-                         struct ace_condition_bytes *tok)
+                         DATA_BLOB *tok)
 {
-       if (length < 4) {
+       ssize_t bytes_used;
+       enum ndr_err_code ndr_err;
+       DATA_BLOB v = data_blob_const(data, length);
+       struct ndr_pull *ndr = ndr_pull_init_blob(&v, mem_ctx);
+       if (ndr == NULL) {
                return -1;
        }
-       tok->length = PULL_LE_U32(data, 0);
-       if (tok->length > length - 4) {
+       ndr_err = ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, tok);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               TALLOC_FREE(ndr);
                return -1;
        }
-       tok->bytes = talloc_size(mem_ctx, tok->length + 1);
-       if (tok->bytes == NULL) {
+       bytes_used = ndr->offset;
+       talloc_free(ndr);
+       return bytes_used;
+}
+
+static ssize_t push_bytes(uint8_t *data, size_t available,
+                       const DATA_BLOB *tok)
+{
+       size_t offset;
+       enum ndr_err_code ndr_err;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct ndr_push *ndr = ndr_push_init_ctx(frame);
+       if (ndr == NULL) {
+               TALLOC_FREE(frame);
                return -1;
        }
-       memcpy(tok->bytes, data + 4, tok->length);
-       tok->bytes[tok->length] = 0;
-       return tok->length + 4;
-}
 
+       ndr_err = ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, *tok);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               TALLOC_FREE(frame);
+               return -1;
+       }
 
-static ssize_t push_bytes(uint8_t *data, size_t length,
-                         const struct ace_condition_bytes *tok)
-{
-       if (length < tok->length + 4) {
+       if (available < ndr->offset) {
+               TALLOC_FREE(frame);
                return -1;
        }
-       PUSH_LE_U32(data, 0, tok->length);
-       memcpy(data + 4, tok->bytes, tok->length);
-       return tok->length + 4;
+       memcpy(data, ndr->data, ndr->offset);
+       offset = ndr->offset;
+       TALLOC_FREE(frame);
+       return offset;
 }
 
-
 static ssize_t pull_sid(TALLOC_CTX *mem_ctx,
                        uint8_t *data, size_t length,
                        struct ace_condition_sid *tok)
@@ -1376,12 +1393,9 @@ static bool compare_bytes(const struct ace_condition_token *op,
                          const struct ace_condition_token *rhs,
                          int *cmp)
 {
-       struct ace_condition_bytes a = lhs->data.bytes;
-       struct ace_condition_bytes b = rhs->data.bytes;
-       *cmp = memcmp(a.bytes, b.bytes, MIN(a.length, b.length));
-       if (*cmp == 0) {
-               *cmp = a.length - b.length;
-       }
+       DATA_BLOB a = lhs->data.bytes;
+       DATA_BLOB b = rhs->data.bytes;
+       *cmp = data_blob_cmp(&a, &b);
        return true;
 }
 
index 1349a7fbf3b1f5849b7452908a1b2413f548997f..c32991a092bcb22cfbc9bb65f82b4f33458a3fc7 100644 (file)
@@ -551,7 +551,7 @@ char *debug_conditional_ace(TALLOC_CTX *mem_ctx,
 
                case CONDITIONAL_ACE_TOKEN_OCTET_STRING:
                        utf8_len = MIN(tok->data.bytes.length, 9);
-                       hex_encode_buf(hex, tok->data.bytes.bytes, utf8_len);
+                       hex_encode_buf(hex, tok->data.bytes.data, utf8_len);
 
                        snprintf(line, sizeof(line),
                                 "%s %.*s (%d)\n",
@@ -865,7 +865,7 @@ static bool sddl_write_octet_string(struct sddl_write_context *ctx,
 {
        bool ok;
        char *hex  = hex_encode_talloc(ctx->mem_ctx,
-                                      tok->data.bytes.bytes,
+                                      tok->data.bytes.data,
                                       tok->data.bytes.length);
        ok = sddl_write(ctx, "#");
        if (!ok) {
@@ -1909,8 +1909,7 @@ static bool parse_octet_string(struct ace_condition_sddl_compiler_context *comp)
 
        length /= 2;
 
-       token.data.bytes.bytes = talloc_array(comp->mem_ctx, uint8_t, length);
-       token.data.bytes.length = length;
+       token.data.bytes = data_blob_talloc_zero(comp->mem_ctx, length);
        token.type = CONDITIONAL_ACE_TOKEN_OCTET_STRING;
 
        for (i = 0; i < length; i++) {
@@ -1932,9 +1931,9 @@ static bool parse_octet_string(struct ace_condition_sddl_compiler_context *comp)
                pair[0] = (comp->sddl[j]     == '#') ? '0' : comp->sddl[j];
                pair[1] = (comp->sddl[j + 1] == '#') ? '0' : comp->sddl[j + 1];
 
-               ok = hex_byte(pair, &token.data.bytes.bytes[i]);
+               ok = hex_byte(pair, &token.data.bytes.data[i]);
                if (!ok) {
-                       talloc_free(token.data.bytes.bytes);
+                       talloc_free(token.data.bytes.data);
                        comp_error(comp, "inexplicable error in octet string");
                        return false;
                }
index fc97d75189a66fd51d6e92fd32f664a1664ee18f..0630dac370ea808a402f35beed9e5242e68d20e4 100644 (file)
@@ -280,11 +280,6 @@ interface conditional_ace
                uint32 length;
        } ace_condition_unicode;
 
-       typedef struct {
-               uint8 *bytes;
-               uint32 length;
-       } ace_condition_bytes;
-
        typedef [public] struct {
                [subcontext(4)] dom_sid sid;
        } ace_condition_sid;
@@ -323,7 +318,7 @@ interface conditional_ace
        typedef [nodiscriminant] union {
                [case(CONDITIONAL_ACE_TOKEN_SID)] ace_condition_sid sid;
                [case(CONDITIONAL_ACE_TOKEN_COMPOSITE)]ace_condition_composite composite;
-               [case(CONDITIONAL_ACE_TOKEN_OCTET_STRING)] ace_condition_bytes bytes;
+               [case(CONDITIONAL_ACE_TOKEN_OCTET_STRING)] DATA_BLOB bytes;
                [case(CONDITIONAL_ACE_TOKEN_UNICODE)]ace_condition_unicode unicode;
 
                [case(CONDITIONAL_ACE_LOCAL_ATTRIBUTE)]ace_condition_unicode local_attr;