diff options
author | Andrew Bartlett <abartlet@samba.org> | 2023-03-16 19:06:04 +1300 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2023-03-31 01:48:30 +0000 |
commit | 2d2f68236e6d34d96dc6bdceb13ff54bedde46fb (patch) | |
tree | 2e6da923b1dedfec7662744ee4801d530a8f98eb /librpc | |
parent | c6981f60549c497d401c4c4173dc362f083791d7 (diff) | |
download | samba-2d2f68236e6d34d96dc6bdceb13ff54bedde46fb.tar.gz |
librpc/ndr: Use libndr compression for claims
This ensures our python layer and C layer (in the KDC, when implementated)
use the same compression logic and so allows us to test the production
compression via the IDL-generated interfaces.
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Diffstat (limited to 'librpc')
-rw-r--r-- | librpc/idl/claims.idl | 42 | ||||
-rw-r--r-- | librpc/ndr/ndr_claims.c | 84 | ||||
-rw-r--r-- | librpc/ndr/ndr_claims.h | 34 | ||||
-rw-r--r-- | librpc/wscript_build | 4 |
4 files changed, 156 insertions, 8 deletions
diff --git a/librpc/idl/claims.idl b/librpc/idl/claims.idl index ed84cd772c1..388965a4239 100644 --- a/librpc/idl/claims.idl +++ b/librpc/idl/claims.idl @@ -19,13 +19,16 @@ uuid("bba9cb76-eb0c-462c-aa1b-5d8c34415701"), version(1.0), pointer_default(unique), - helpstring("Active Directory Claims") + helpstring("Active Directory Claims"), + helper("../librpc/ndr/ndr_claims.h") ] interface claims { #define wchar_t uint16 #define CLAIM_ID [string, charset(UTF16)] wchar_t * + const int CLAIM_MINIMUM_BYTES_TO_COMPRESS = 384; + typedef enum { CLAIM_TYPE_INT64 = 1, CLAIM_TYPE_UINT64 = 2, @@ -98,7 +101,7 @@ interface claims [size_is(reserved_field_size)] uint8 *reserved_field; } CLAIMS_SET; - typedef [public] struct { + typedef [public, gensize] struct { [subcontext(0xFFFFFC01)] CLAIMS_SET_CTR claims; } CLAIMS_SET_NDR; @@ -107,10 +110,37 @@ interface claims } CLAIMS_SET_METADATA_NDR; typedef [public] struct { - uint32 claims_set_size; - [size_is(claims_set_size)] uint8 *claims_set; - CLAIMS_COMPRESSION_FORMAT compression_format; - uint32 uncompressed_claims_set_size; + [value(ndr_claims_compressed_size(claims_set, + r->compression_format, + ndr->flags))] uint32 claims_set_size; + [subcontext(4), + compression(ndr_claims_compression_alg(compression_format), + claims_set_size, + uncompressed_claims_set_size) + ] CLAIMS_SET_NDR *claims_set; + /* + * The second argument to + * ndr_claims_actual_wire_compression_alg() in the + * value() below should be + * uncompressed_claims_set_size but the value() + * handling isn't recursive (enough) so we have to + * specify that manually otherwise the + * compression_format in the above includes the struct + * member, not the value() + * + * The caller should set compression_format to + * CLAIMS_COMPRESSION_FORMAT_XPRESS_HUFF and this will + * be reset to CLAIMS_COMPRESSION_FORMAT_NONE if the + * buffer is not large enough to compress. + * + * Otherwise setting CLAIMS_COMPRESSION_FORMAT_NONE + * disabled compression entirely. + */ + [value(ndr_claims_actual_wire_compression_alg(r->compression_format, + ndr_size_CLAIMS_SET_NDR(claims_set, + ndr->flags)))] CLAIMS_COMPRESSION_FORMAT compression_format; + [value(ndr_size_CLAIMS_SET_NDR(claims_set, + ndr->flags))] uint32 uncompressed_claims_set_size; uint16 reserved_type; uint32 reserved_field_size; [size_is(reserved_field_size)] uint8 *reserved_field; diff --git a/librpc/ndr/ndr_claims.c b/librpc/ndr/ndr_claims.c new file mode 100644 index 00000000000..fbfe612fbf4 --- /dev/null +++ b/librpc/ndr/ndr_claims.c @@ -0,0 +1,84 @@ +#include "includes.h" +#include "bin/default/librpc/gen_ndr/ndr_claims.h" +#include "librpc/ndr/ndr_claims.h" + +#include "librpc/ndr/ndr_compression.h" +#include "lib/compression/lzxpress_huffman.h" + +enum ndr_compression_alg ndr_claims_compression_alg(enum CLAIMS_COMPRESSION_FORMAT wire_alg) +{ + switch (wire_alg) { + case CLAIMS_COMPRESSION_FORMAT_NONE: + return NDR_COMPRESSION_NONE; + + case CLAIMS_COMPRESSION_FORMAT_LZNT1: + return NDR_COMPRESSION_INVALID; + + case CLAIMS_COMPRESSION_FORMAT_XPRESS: + return NDR_COMPRESSION_INVALID; + + case CLAIMS_COMPRESSION_FORMAT_XPRESS_HUFF: + return NDR_COMPRESSION_XPRESS_HUFF_RAW; + } + return NDR_COMPRESSION_INVALID; +} + + +enum CLAIMS_COMPRESSION_FORMAT ndr_claims_actual_wire_compression_alg(enum CLAIMS_COMPRESSION_FORMAT specified_compression, + size_t uncompressed_claims_size) { + if (uncompressed_claims_size < CLAIM_MINIMUM_BYTES_TO_COMPRESS) { + return CLAIMS_COMPRESSION_FORMAT_NONE; + } + + return specified_compression; +} + +size_t ndr_claims_compressed_size(struct CLAIMS_SET_NDR *claims_set, + enum CLAIMS_COMPRESSION_FORMAT wire_alg, + int flags) +{ + TALLOC_CTX *frame = talloc_stackframe(); + DATA_BLOB tmp_blob; + uint8_t * tmp_compressed; + ssize_t compressed_size; + enum ndr_err_code ndr_err; + enum CLAIMS_COMPRESSION_FORMAT actual_wire_alg; + + ndr_err = ndr_push_struct_blob(&tmp_blob, + frame, + claims_set, + (ndr_push_flags_fn_t)ndr_push_CLAIMS_SET_NDR); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DBG_ERR("Failed to push claims while determining compressed size"); + TALLOC_FREE(frame); + return 0; + } + + actual_wire_alg = ndr_claims_actual_wire_compression_alg(wire_alg, + tmp_blob.length); + + switch (actual_wire_alg) { + case CLAIMS_COMPRESSION_FORMAT_NONE: + TALLOC_FREE(frame); + return tmp_blob.length; + + case CLAIMS_COMPRESSION_FORMAT_XPRESS_HUFF: + compressed_size = lzxpress_huffman_compress_talloc(frame, + tmp_blob.data, + tmp_blob.length, + &tmp_compressed); + + TALLOC_FREE(frame); + + if (compressed_size < 0) { + DBG_ERR("Failed to compress claims (for determining compressed size)"); + return 0; + } + return compressed_size; + + default: + TALLOC_FREE(frame); + DBG_ERR("Invalid chosen compression algorithm while determining compressed claim size"); + return 0; + } +} diff --git a/librpc/ndr/ndr_claims.h b/librpc/ndr/ndr_claims.h new file mode 100644 index 00000000000..03f40466762 --- /dev/null +++ b/librpc/ndr/ndr_claims.h @@ -0,0 +1,34 @@ +/* + Unix SMB/CIFS implementation. + + routines for helping the compression in claims + + Copyright (C) Andrew Bartlett 2023 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _LIBRPC_NDR_NDR_CLAIMS_H +#define _LIBRPC_NDR_NDR_CLAIMS_H + +enum ndr_compression_alg ndr_claims_compression_alg(enum CLAIMS_COMPRESSION_FORMAT wire_alg); +enum CLAIMS_COMPRESSION_FORMAT ndr_claims_actual_wire_compression_alg(enum CLAIMS_COMPRESSION_FORMAT specified_compression, + size_t uncompressed_claims_size); + +size_t ndr_claims_compressed_size(struct CLAIMS_SET_NDR *claims_set, + enum CLAIMS_COMPRESSION_FORMAT wire_alg, + int flags); + + +#endif /* _LIBRPC_NDR_NDR_CLAIMS_H */ diff --git a/librpc/wscript_build b/librpc/wscript_build index b474646be44..cd1988033d2 100644 --- a/librpc/wscript_build +++ b/librpc/wscript_build @@ -385,8 +385,8 @@ bld.SAMBA_SUBSYSTEM('NDR_KRB5CCACHE', ) bld.SAMBA_SUBSYSTEM('NDR_CLAIMS', - source='gen_ndr/ndr_claims.c', - deps='ndr') + source='gen_ndr/ndr_claims.c ndr/ndr_claims.c', + deps='ndr NDR_COMPRESSION LZXPRESS') bld.SAMBA_LIBRARY('ndr-standard', source='', |