summaryrefslogtreecommitdiff
path: root/librpc
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2023-03-16 19:06:04 +1300
committerAndrew Bartlett <abartlet@samba.org>2023-03-31 01:48:30 +0000
commit2d2f68236e6d34d96dc6bdceb13ff54bedde46fb (patch)
tree2e6da923b1dedfec7662744ee4801d530a8f98eb /librpc
parentc6981f60549c497d401c4c4173dc362f083791d7 (diff)
downloadsamba-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.idl42
-rw-r--r--librpc/ndr/ndr_claims.c84
-rw-r--r--librpc/ndr/ndr_claims.h34
-rw-r--r--librpc/wscript_build4
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='',