From 8daa83a594a2e98f39d764422bfbdbc62c9efd44 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 19:20:00 +0200 Subject: Adding upstream version 2:4.20.0+dfsg. Signed-off-by: Daniel Baumann --- source4/torture/drs/drs_util.c | 167 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 source4/torture/drs/drs_util.c (limited to 'source4/torture/drs/drs_util.c') diff --git a/source4/torture/drs/drs_util.c b/source4/torture/drs/drs_util.c new file mode 100644 index 0000000..c43836e --- /dev/null +++ b/source4/torture/drs/drs_util.c @@ -0,0 +1,167 @@ +/* + Unix SMB/CIFS implementation. + + DRSUAPI utility functions to be used in torture tests + + Copyright (C) Kamen Mazdrashki 2009 + + 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 . +*/ + +#include "includes.h" +#include "torture/torture.h" +#include "dsdb/samdb/samdb.h" +#include "torture/rpc/drsuapi.h" +#include "../lib/util/asn1.h" +#include "torture/drs/proto.h" + +/** + * Decode Attribute OID based on MS documentation + * See MS-DRSR.pdf - 5.16.4 + * + * On success returns decoded OID and + * corresponding prefix_map index (if requested) + */ +bool drs_util_oid_from_attid(struct torture_context *tctx, + const struct drsuapi_DsReplicaOIDMapping_Ctr *prefix_map, + uint32_t attid, + const char **_oid, + int *map_idx) +{ + uint32_t i, hi_word, lo_word; + DATA_BLOB bin_oid = {NULL, 0}; + char *oid; + struct drsuapi_DsReplicaOIDMapping *map_entry = NULL; + TALLOC_CTX *mem_ctx = talloc_named(tctx, 0, "util_drsuapi_oid_from_attid"); + + /* crack attid value */ + hi_word = attid >> 16; + lo_word = attid & 0xFFFF; + + /* check last entry in the prefix map is the special one */ + map_entry = &prefix_map->mappings[prefix_map->num_mappings-1]; + torture_assert(tctx, + (map_entry->id_prefix == 0) + && (*map_entry->oid.binary_oid == 0xFF), + "Last entry in Prefix Map is not the special one!"); + + /* locate corresponding prefixMap entry */ + map_entry = NULL; + for (i = 0; i < prefix_map->num_mappings - 1; i++) { + + if (hi_word == prefix_map->mappings[i].id_prefix) { + map_entry = &prefix_map->mappings[i]; + if (map_idx) *map_idx = i; + break; + } + } + + torture_assert(tctx, map_entry, "Unable to locate corresponding Prefix Map entry"); + + /* copy partial oid making enough room */ + bin_oid.length = map_entry->oid.length + 2; + bin_oid.data = talloc_array(mem_ctx, uint8_t, bin_oid.length); + torture_assert(tctx, bin_oid.data, "Not enough memory"); + memcpy(bin_oid.data, map_entry->oid.binary_oid, map_entry->oid.length); + + if (lo_word < 128) { + bin_oid.length = bin_oid.length - 1; + bin_oid.data[bin_oid.length-1] = lo_word; + } + else { + if (lo_word >= 32768) { + lo_word -= 32768; + } + bin_oid.data[bin_oid.length-2] = ((lo_word / 128) % 128) + 128; /* (0x80 | ((lo_word>>7) & 0x7f)) */ + bin_oid.data[bin_oid.length-1] = lo_word % 128; /* lo_word & 0x7f */ + } + + torture_assert(tctx, + ber_read_OID_String(tctx, bin_oid, &oid), + "Failed to decode binary OID"); + talloc_free(mem_ctx); + + *_oid = oid; + + return true; +} + + +/** + * Loads dsdb_schema from ldb connection using remote prefixMap. + * Schema will be loaded only if: + * - ldb has no attached schema + * - reload_schema is true + * + * This function is to be used in tests that use GetNCChanges() function + */ +bool drs_util_dsdb_schema_load_ldb(struct torture_context *tctx, + struct ldb_context *ldb, + const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr, + bool reload_schema) +{ + int ret; + WERROR werr; + char *err_msg; + struct ldb_result *res; + struct ldb_dn *schema_dn; + struct dsdb_schema *ldap_schema; + + ldap_schema = dsdb_get_schema(ldb, NULL); + if (ldap_schema && !reload_schema) { + return true; + } + + schema_dn = ldb_get_schema_basedn(ldb); + torture_assert(tctx, schema_dn != NULL, + talloc_asprintf(tctx, "ldb_get_schema_basedn() failed: %s", ldb_errstring(ldb))); + + ldap_schema = dsdb_new_schema(ldb); + torture_assert(tctx, ldap_schema != NULL, "dsdb_new_schema() failed!"); + + werr = dsdb_load_prefixmap_from_drsuapi(ldap_schema, mapping_ctr); + torture_assert_werr_ok(tctx, werr, + "Failed to construct prefixMap from drsuapi data"); + + /* + * load the attribute and objectClass definitions + */ + ret = ldb_search(ldb, ldap_schema, &res, + schema_dn, LDB_SCOPE_ONELEVEL, NULL, + "(|(objectClass=attributeSchema)(objectClass=classSchema))"); + if (ret != LDB_SUCCESS) { + err_msg = talloc_asprintf(tctx, + "failed to search attributeSchema or classSchema objects: %s", + ldb_errstring(ldb)); + torture_fail(tctx, err_msg); + } + + ret = dsdb_load_ldb_results_into_schema(tctx, ldb, ldap_schema, res, &err_msg); + if (ret != LDB_SUCCESS) { + err_msg = talloc_asprintf(tctx, + "dsdb_load_ldb_results_into_schema failed: %s", + err_msg); + torture_fail(tctx, err_msg); + } + + talloc_free(res); + + ret = dsdb_set_schema(ldb, ldap_schema, SCHEMA_WRITE); + if (ret != LDB_SUCCESS) { + torture_fail(tctx, + talloc_asprintf(tctx, "dsdb_set_schema() failed: %s", ldb_strerror(ret))); + } + + return true; +} -- cgit v1.2.3