From: Andrew Bartlett Date: Thu, 21 Sep 2023 00:55:53 +0000 (+1200) Subject: conditional_aces: Avoid manual parsing for ace_condition_bytes, use DATA_BLOB X-Git-Tag: tevent-0.16.0~414 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=793b86f4cbfa763002246b6ff1cd1197622704ca;p=thirdparty%2Fsamba.git conditional_aces: Avoid manual parsing for ace_condition_bytes, use DATA_BLOB Signed-off-by: Andrew Bartlett Reviewed-by: Douglas Bagnall --- diff --git a/lib/util/data_blob.c b/lib/util/data_blob.c index 677f7c19211..69a340c6fb8 100644 --- a/lib/util/data_blob.c +++ b/lib/util/data_blob.c @@ -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; diff --git a/libcli/security/claims-conversions.c b/libcli/security/claims-conversions.c index 176d23567d6..9bb09c01360 100644 --- a/libcli/security/claims-conversions.c +++ b/libcli/security/claims-conversions.c @@ -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; diff --git a/libcli/security/conditional_ace.c b/libcli/security/conditional_ace.c index 569bdd82696..2957dc20319 100644 --- a/libcli/security/conditional_ace.c +++ b/libcli/security/conditional_ace.c @@ -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; } diff --git a/libcli/security/sddl_conditional_ace.c b/libcli/security/sddl_conditional_ace.c index 1349a7fbf3b..c32991a092b 100644 --- a/libcli/security/sddl_conditional_ace.c +++ b/libcli/security/sddl_conditional_ace.c @@ -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; } diff --git a/librpc/idl/conditional_ace.idl b/librpc/idl/conditional_ace.idl index fc97d75189a..0630dac370e 100644 --- a/librpc/idl/conditional_ace.idl +++ b/librpc/idl/conditional_ace.idl @@ -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;