s3:smbd: s/event_add_fd/tevent_add_fd and s/EVENT_FD_/TEVENT_FD_
[Samba/gebeck_regimport.git] / source4 / torture / drs / unit / prefixmap_tests.c
blob29941ebec6dedf3971a020ab1d0ca5ca433d4244
1 /*
2 Unix SMB/CIFS implementation.
4 DRSUAPI prefixMap unit tests
6 Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2009-2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "torture/smbtorture.h"
25 #include "dsdb/samdb/samdb.h"
26 #include "torture/rpc/drsuapi.h"
27 #include "torture/drs/proto.h"
28 #include "param/param.h"
31 /**
32 * Private data to be shared among all test in Test case
34 struct drsut_prefixmap_data {
35 struct dsdb_schema_prefixmap *pfm_new;
36 struct dsdb_schema_prefixmap *pfm_full;
38 /* default schemaInfo value to test with */
39 const char *schi_default_str;
40 struct dsdb_schema_info *schi_default;
42 struct ldb_context *ldb_ctx;
45 /**
46 * Test-oid data structure
48 struct drsut_pfm_oid_data {
49 uint32_t id;
50 const char *bin_oid;
51 const char *oid_prefix;
54 /**
55 * Default prefixMap initialization data.
56 * This prefixMap is what dsdb_schema_pfm_new() should return.
57 * Based on: MS-DRSR, 5.16.4 ATTRTYP-to-OID Conversion
58 * procedure NewPrefixTable( )
60 static const struct drsut_pfm_oid_data _prefixmap_test_new_data[] = {
61 {.id=0x00000000, .bin_oid="5504", .oid_prefix="2.5.4"},
62 {.id=0x00000001, .bin_oid="5506", .oid_prefix="2.5.6"},
63 {.id=0x00000002, .bin_oid="2A864886F7140102", .oid_prefix="1.2.840.113556.1.2"},
64 {.id=0x00000003, .bin_oid="2A864886F7140103", .oid_prefix="1.2.840.113556.1.3"},
65 {.id=0x00000004, .bin_oid="6086480165020201", .oid_prefix="2.16.840.1.101.2.2.1"},
66 {.id=0x00000005, .bin_oid="6086480165020203", .oid_prefix="2.16.840.1.101.2.2.3"},
67 {.id=0x00000006, .bin_oid="6086480165020105", .oid_prefix="2.16.840.1.101.2.1.5"},
68 {.id=0x00000007, .bin_oid="6086480165020104", .oid_prefix="2.16.840.1.101.2.1.4"},
69 {.id=0x00000008, .bin_oid="5505", .oid_prefix="2.5.5"},
70 {.id=0x00000009, .bin_oid="2A864886F7140104", .oid_prefix="1.2.840.113556.1.4"},
71 {.id=0x0000000A, .bin_oid="2A864886F7140105", .oid_prefix="1.2.840.113556.1.5"},
72 {.id=0x00000013, .bin_oid="0992268993F22C64", .oid_prefix="0.9.2342.19200300.100"},
73 {.id=0x00000014, .bin_oid="6086480186F84203", .oid_prefix="2.16.840.1.113730.3"},
74 {.id=0x00000015, .bin_oid="0992268993F22C6401", .oid_prefix="0.9.2342.19200300.100.1"},
75 {.id=0x00000016, .bin_oid="6086480186F8420301", .oid_prefix="2.16.840.1.113730.3.1"},
76 {.id=0x00000017, .bin_oid="2A864886F7140105B658", .oid_prefix="1.2.840.113556.1.5.7000"},
77 {.id=0x00000018, .bin_oid="5515", .oid_prefix="2.5.21"},
78 {.id=0x00000019, .bin_oid="5512", .oid_prefix="2.5.18"},
79 {.id=0x0000001A, .bin_oid="5514", .oid_prefix="2.5.20"},
82 /**
83 * Data to be used for creating full prefix map for testing.
84 * 'full-prefixMap' is based on what w2k8 returns as a prefixMap
85 * on clean installation - i.e. prefixMap for clean Schema
87 static const struct drsut_pfm_oid_data _prefixmap_full_map_data[] = {
88 {.id=0x00000000, .bin_oid="0x5504", .oid_prefix="2.5.4"},
89 {.id=0x00000001, .bin_oid="0x5506", .oid_prefix="2.5.6"},
90 {.id=0x00000002, .bin_oid="0x2A864886F7140102", .oid_prefix="1.2.840.113556.1.2"},
91 {.id=0x00000003, .bin_oid="0x2A864886F7140103", .oid_prefix="1.2.840.113556.1.3"},
92 {.id=0x00000004, .bin_oid="0x6086480165020201", .oid_prefix="2.16.840.1.101.2.2.1"},
93 {.id=0x00000005, .bin_oid="0x6086480165020203", .oid_prefix="2.16.840.1.101.2.2.3"},
94 {.id=0x00000006, .bin_oid="0x6086480165020105", .oid_prefix="2.16.840.1.101.2.1.5"},
95 {.id=0x00000007, .bin_oid="0x6086480165020104", .oid_prefix="2.16.840.1.101.2.1.4"},
96 {.id=0x00000008, .bin_oid="0x5505", .oid_prefix="2.5.5"},
97 {.id=0x00000009, .bin_oid="0x2A864886F7140104", .oid_prefix="1.2.840.113556.1.4"},
98 {.id=0x0000000a, .bin_oid="0x2A864886F7140105", .oid_prefix="1.2.840.113556.1.5"},
99 {.id=0x00000013, .bin_oid="0x0992268993F22C64", .oid_prefix="0.9.2342.19200300.100"},
100 {.id=0x00000014, .bin_oid="0x6086480186F84203", .oid_prefix="2.16.840.1.113730.3"},
101 {.id=0x00000015, .bin_oid="0x0992268993F22C6401", .oid_prefix="0.9.2342.19200300.100.1"},
102 {.id=0x00000016, .bin_oid="0x6086480186F8420301", .oid_prefix="2.16.840.1.113730.3.1"},
103 {.id=0x00000017, .bin_oid="0x2A864886F7140105B658", .oid_prefix="1.2.840.113556.1.5.7000"},
104 {.id=0x00000018, .bin_oid="0x5515", .oid_prefix="2.5.21"},
105 {.id=0x00000019, .bin_oid="0x5512", .oid_prefix="2.5.18"},
106 {.id=0x0000001a, .bin_oid="0x5514", .oid_prefix="2.5.20"},
107 {.id=0x0000000b, .bin_oid="0x2A864886F71401048204", .oid_prefix="1.2.840.113556.1.4.260"},
108 {.id=0x0000000c, .bin_oid="0x2A864886F714010538", .oid_prefix="1.2.840.113556.1.5.56"},
109 {.id=0x0000000d, .bin_oid="0x2A864886F71401048206", .oid_prefix="1.2.840.113556.1.4.262"},
110 {.id=0x0000000e, .bin_oid="0x2A864886F714010539", .oid_prefix="1.2.840.113556.1.5.57"},
111 {.id=0x0000000f, .bin_oid="0x2A864886F71401048207", .oid_prefix="1.2.840.113556.1.4.263"},
112 {.id=0x00000010, .bin_oid="0x2A864886F71401053A", .oid_prefix="1.2.840.113556.1.5.58"},
113 {.id=0x00000011, .bin_oid="0x2A864886F714010549", .oid_prefix="1.2.840.113556.1.5.73"},
114 {.id=0x00000012, .bin_oid="0x2A864886F71401048231", .oid_prefix="1.2.840.113556.1.4.305"},
115 {.id=0x0000001b, .bin_oid="0x2B060104018B3A6577", .oid_prefix="1.3.6.1.4.1.1466.101.119"},
116 {.id=0x0000001c, .bin_oid="0x6086480186F8420302", .oid_prefix="2.16.840.1.113730.3.2"},
117 {.id=0x0000001d, .bin_oid="0x2B06010401817A01", .oid_prefix="1.3.6.1.4.1.250.1"},
118 {.id=0x0000001e, .bin_oid="0x2A864886F70D0109", .oid_prefix="1.2.840.113549.1.9"},
119 {.id=0x0000001f, .bin_oid="0x0992268993F22C6404", .oid_prefix="0.9.2342.19200300.100.4"},
120 {.id=0x00000020, .bin_oid="0x2A864886F714010617", .oid_prefix="1.2.840.113556.1.6.23"},
121 {.id=0x00000021, .bin_oid="0x2A864886F71401061201", .oid_prefix="1.2.840.113556.1.6.18.1"},
122 {.id=0x00000022, .bin_oid="0x2A864886F71401061202", .oid_prefix="1.2.840.113556.1.6.18.2"},
123 {.id=0x00000023, .bin_oid="0x2A864886F71401060D03", .oid_prefix="1.2.840.113556.1.6.13.3"},
124 {.id=0x00000024, .bin_oid="0x2A864886F71401060D04", .oid_prefix="1.2.840.113556.1.6.13.4"},
125 {.id=0x00000025, .bin_oid="0x2B0601010101", .oid_prefix="1.3.6.1.1.1.1"},
126 {.id=0x00000026, .bin_oid="0x2B0601010102", .oid_prefix="1.3.6.1.1.1.2"},
127 {.id=0x000003ed, .bin_oid="0x2A864886F7140104B65866", .oid_prefix="1.2.840.113556.1.4.7000.102"},
128 {.id=0x00000428, .bin_oid="0x2A864886F7140105B6583E", .oid_prefix="1.2.840.113556.1.5.7000.62"},
129 {.id=0x0000044c, .bin_oid="0x2A864886F7140104B6586683", .oid_prefix="1.2.840.113556.1.4.7000.102:0x83"},
130 {.id=0x0000044f, .bin_oid="0x2A864886F7140104B6586681", .oid_prefix="1.2.840.113556.1.4.7000.102:0x81"},
131 {.id=0x0000047d, .bin_oid="0x2A864886F7140105B6583E81", .oid_prefix="1.2.840.113556.1.5.7000.62:0x81"},
132 {.id=0x00000561, .bin_oid="0x2A864886F7140105B6583E83", .oid_prefix="1.2.840.113556.1.5.7000.62:0x83"},
133 {.id=0x000007d1, .bin_oid="0x2A864886F71401061401", .oid_prefix="1.2.840.113556.1.6.20.1"},
134 {.id=0x000007e1, .bin_oid="0x2A864886F71401061402", .oid_prefix="1.2.840.113556.1.6.20.2"},
135 {.id=0x00001b86, .bin_oid="0x2A817A", .oid_prefix="1.2.250"},
136 {.id=0x00001c78, .bin_oid="0x2A817A81", .oid_prefix="1.2.250:0x81"},
137 {.id=0x00001c7b, .bin_oid="0x2A817A8180", .oid_prefix="1.2.250:0x8180"},
142 * OID-to-ATTID mappings to be used for testing.
143 * An entry is marked as 'exists=true' if it exists in
144 * base prefixMap (_prefixmap_test_new_data)
146 static const struct {
147 const char *oid;
148 uint32_t id;
149 uint32_t attid;
150 bool exists;
151 } _prefixmap_test_data[] = {
152 {.oid="2.5.4.0", .id=0x00000000, .attid=0x000000, .exists=true},
153 {.oid="2.5.4.42", .id=0x00000000, .attid=0x00002a, .exists=true},
154 {.oid="1.2.840.113556.1.2.1", .id=0x00000002, .attid=0x020001, .exists=true},
155 {.oid="1.2.840.113556.1.2.13", .id=0x00000002, .attid=0x02000d, .exists=true},
156 {.oid="1.2.840.113556.1.2.281", .id=0x00000002, .attid=0x020119, .exists=true},
157 {.oid="1.2.840.113556.1.4.125", .id=0x00000009, .attid=0x09007d, .exists=true},
158 {.oid="1.2.840.113556.1.4.146", .id=0x00000009, .attid=0x090092, .exists=true},
159 {.oid="1.2.250.1", .id=0x00001b86, .attid=0x1b860001, .exists=false},
160 {.oid="1.2.250.16386", .id=0x00001c78, .attid=0x1c788002, .exists=false},
161 {.oid="1.2.250.2097154", .id=0x00001c7b, .attid=0x1c7b8002, .exists=false},
166 * Creates dsdb_schema_prefixmap based on predefined data
168 static WERROR _drsut_prefixmap_new(const struct drsut_pfm_oid_data *_pfm_init_data, uint32_t count,
169 TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_pfm)
171 uint32_t i;
172 struct dsdb_schema_prefixmap *pfm;
174 pfm = talloc(mem_ctx, struct dsdb_schema_prefixmap);
175 W_ERROR_HAVE_NO_MEMORY(pfm);
177 pfm->length = count;
178 pfm->prefixes = talloc_array(pfm, struct dsdb_schema_prefixmap_oid, pfm->length);
179 if (!pfm->prefixes) {
180 talloc_free(pfm);
181 return WERR_NOMEM;
184 for (i = 0; i < pfm->length; i++) {
185 pfm->prefixes[i].id = _pfm_init_data[i].id;
186 pfm->prefixes[i].bin_oid = strhex_to_data_blob(pfm, _pfm_init_data[i].bin_oid);
187 if (!pfm->prefixes[i].bin_oid.data) {
188 talloc_free(pfm);
189 return WERR_NOMEM;
193 *_pfm = pfm;
195 return WERR_OK;
199 * Compares two prefixMaps for being equal - same items on same indexes
201 static bool _torture_drs_pfm_compare_same(struct torture_context *tctx,
202 const struct dsdb_schema_prefixmap *pfm_left,
203 const struct dsdb_schema_prefixmap *pfm_right,
204 bool quiet)
206 uint32_t i;
207 char *err_msg = NULL;
209 if (pfm_left->length != pfm_right->length) {
210 err_msg = talloc_asprintf(tctx, "prefixMaps differ in size; left = %d, right = %d",
211 pfm_left->length, pfm_right->length);
212 goto failed;
215 for (i = 0; i < pfm_left->length; i++) {
216 struct dsdb_schema_prefixmap_oid *entry_left = &pfm_left->prefixes[i];
217 struct dsdb_schema_prefixmap_oid *entry_right = &pfm_right->prefixes[i];
219 if (entry_left->id != entry_right->id) {
220 err_msg = talloc_asprintf(tctx, "Different IDs for index=%d", i);
221 goto failed;
223 if (data_blob_cmp(&entry_left->bin_oid, &entry_right->bin_oid)) {
224 err_msg = talloc_asprintf(tctx, "Different bin_oid for index=%d", i);
225 goto failed;
229 return true;
231 failed:
232 if (!quiet) {
233 torture_comment(tctx, "_torture_drs_pfm_compare_same: %s", err_msg);
235 talloc_free(err_msg);
237 return false;
241 * Tests dsdb_schema_pfm_new()
243 static bool torture_drs_unit_pfm_new(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
245 WERROR werr;
246 bool bret;
247 TALLOC_CTX *mem_ctx;
248 struct dsdb_schema_prefixmap *pfm = NULL;
250 mem_ctx = talloc_new(priv);
252 /* create new prefix map */
253 werr = dsdb_schema_pfm_new(mem_ctx, &pfm);
254 torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_new() failed!");
255 torture_assert(tctx, pfm != NULL, "NULL prefixMap created!");
256 torture_assert(tctx, pfm->length > 0, "Empty prefixMap created!");
257 torture_assert(tctx, pfm->prefixes != NULL, "No prefixes for newly created prefixMap!");
259 /* compare newly created prefixMap with template one */
260 bret = _torture_drs_pfm_compare_same(tctx, priv->pfm_new, pfm, false);
262 talloc_free(mem_ctx);
264 return bret;
268 * Tests dsdb_schema_pfm_make_attid() using full prefixMap.
269 * In this test we know exactly which ATTID and prefixMap->ID
270 * should be returned, i.e. no prefixMap entries should be added.
272 static bool torture_drs_unit_pfm_make_attid_full_map(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
274 WERROR werr;
275 uint32_t i, count;
276 uint32_t attid;
277 char *err_msg;
279 count = ARRAY_SIZE(_prefixmap_test_data);
280 for (i = 0; i < count; i++) {
281 werr = dsdb_schema_pfm_make_attid(priv->pfm_full, _prefixmap_test_data[i].oid, &attid);
282 /* prepare error message */
283 err_msg = talloc_asprintf(priv, "dsdb_schema_pfm_make_attid() failed with %s",
284 _prefixmap_test_data[i].oid);
285 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
286 /* verify result and returned ATTID */
287 torture_assert_werr_ok(tctx, werr, err_msg);
288 torture_assert_int_equal(tctx, attid, _prefixmap_test_data[i].attid, err_msg);
289 /* reclaim memory for prepared error message */
290 talloc_free(err_msg);
293 return true;
297 * Tests dsdb_schema_pfm_make_attid() using initially small prefixMap.
298 * In this test we don't know exactly which ATTID and prefixMap->ID
299 * should be returned, but we can verify lo-word of ATTID.
300 * This test verifies implementation branch when a new
301 * prefix should be added into prefixMap.
303 static bool torture_drs_unit_pfm_make_attid_small_map(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
305 WERROR werr;
306 uint32_t i, j;
307 uint32_t idx;
308 uint32_t attid, attid_2;
309 char *err_msg;
310 struct dsdb_schema_prefixmap *pfm = NULL;
311 TALLOC_CTX *mem_ctx;
313 mem_ctx = talloc_new(priv);
315 /* create new prefix map */
316 werr = dsdb_schema_pfm_new(mem_ctx, &pfm);
317 torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_new() failed!");
319 /* make some ATTIDs and check result */
320 for (i = 0; i < ARRAY_SIZE(_prefixmap_test_data); i++) {
321 werr = dsdb_schema_pfm_make_attid(pfm, _prefixmap_test_data[i].oid, &attid);
323 /* prepare error message */
324 err_msg = talloc_asprintf(mem_ctx, "dsdb_schema_pfm_make_attid() failed with %s",
325 _prefixmap_test_data[i].oid);
326 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
328 /* verify result and returned ATTID */
329 torture_assert_werr_ok(tctx, werr, err_msg);
330 /* verify ATTID lo-word */
331 torture_assert_int_equal(tctx, attid & 0xFFFF, _prefixmap_test_data[i].attid & 0xFFFF, err_msg);
333 /* try again, this time verify for whole ATTID */
334 werr = dsdb_schema_pfm_make_attid(pfm, _prefixmap_test_data[i].oid, &attid_2);
335 torture_assert_werr_ok(tctx, werr, err_msg);
336 torture_assert_int_equal(tctx, attid_2, attid, err_msg);
338 /* reclaim memory for prepared error message */
339 talloc_free(err_msg);
341 /* check there is such an index in modified prefixMap */
342 idx = (attid >> 16);
343 for (j = 0; j < pfm->length; j++) {
344 if (pfm->prefixes[j].id == idx)
345 break;
347 if (j >= pfm->length) {
348 torture_result(tctx, TORTURE_FAIL, __location__": No prefix for ATTID=0x%08X", attid);
349 return false;
354 talloc_free(mem_ctx);
356 return true;
360 * Tests dsdb_schema_pfm_attid_from_oid() using full prefixMap.
361 * In this test we know exactly which ATTID and prefixMap->ID
362 * should be returned- dsdb_schema_pfm_attid_from_oid() should succeed.
364 static bool torture_drs_unit_pfm_attid_from_oid_full_map(struct torture_context *tctx,
365 struct drsut_prefixmap_data *priv)
367 WERROR werr;
368 uint32_t i, count;
369 uint32_t attid;
370 char *err_msg;
372 count = ARRAY_SIZE(_prefixmap_test_data);
373 for (i = 0; i < count; i++) {
374 werr = dsdb_schema_pfm_attid_from_oid(priv->pfm_full,
375 _prefixmap_test_data[i].oid,
376 &attid);
377 /* prepare error message */
378 err_msg = talloc_asprintf(priv, "dsdb_schema_pfm_attid_from_oid() failed with %s",
379 _prefixmap_test_data[i].oid);
380 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
381 /* verify result and returned ATTID */
382 torture_assert_werr_ok(tctx, werr, err_msg);
383 torture_assert_int_equal(tctx, attid, _prefixmap_test_data[i].attid, err_msg);
384 /* reclaim memory for prepared error message */
385 talloc_free(err_msg);
388 return true;
392 * Tests dsdb_schema_pfm_attid_from_oid() using base (initial) prefixMap.
393 * dsdb_schema_pfm_attid_from_oid() should fail when testing with OID
394 * that are not already in the prefixMap.
396 static bool torture_drs_unit_pfm_attid_from_oid_base_map(struct torture_context *tctx,
397 struct drsut_prefixmap_data *priv)
399 WERROR werr;
400 uint32_t i;
401 uint32_t attid;
402 char *err_msg;
403 struct dsdb_schema_prefixmap *pfm = NULL;
404 struct dsdb_schema_prefixmap pfm_prev;
405 TALLOC_CTX *mem_ctx;
407 mem_ctx = talloc_new(priv);
408 torture_assert(tctx, mem_ctx, "Unexpected: Have no memory!");
410 /* create new prefix map */
411 werr = dsdb_schema_pfm_new(mem_ctx, &pfm);
412 torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_new() failed!");
414 /* keep initial pfm around for testing */
415 pfm_prev = *pfm;
416 pfm_prev.prefixes = talloc_reference(mem_ctx, pfm->prefixes);
418 /* get some ATTIDs and check result */
419 for (i = 0; i < ARRAY_SIZE(_prefixmap_test_data); i++) {
420 werr = dsdb_schema_pfm_attid_from_oid(pfm, _prefixmap_test_data[i].oid, &attid);
422 /* prepare error message */
423 err_msg = talloc_asprintf(mem_ctx,
424 "dsdb_schema_pfm_attid_from_oid() failed for %s",
425 _prefixmap_test_data[i].oid);
426 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
429 /* verify pfm hasn't been altered */
430 if (_prefixmap_test_data[i].exists) {
431 /* should succeed and return valid ATTID */
432 torture_assert_werr_ok(tctx, werr, err_msg);
433 /* verify ATTID */
434 torture_assert_int_equal(tctx,
435 attid, _prefixmap_test_data[i].attid,
436 err_msg);
437 } else {
438 /* should fail */
439 torture_assert_werr_equal(tctx, werr, WERR_NOT_FOUND, err_msg);
442 /* prefixMap should never be changed */
443 if (!_torture_drs_pfm_compare_same(tctx, &pfm_prev, pfm, true)) {
444 torture_fail(tctx, "schema->prefixmap has changed");
447 /* reclaim memory for prepared error message */
448 talloc_free(err_msg);
451 talloc_free(mem_ctx);
453 return true;
457 * Tests dsdb_schema_pfm_oid_from_attid() using full prefixMap.
459 static bool torture_drs_unit_pfm_oid_from_attid(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
461 WERROR werr;
462 uint32_t i, count;
463 char *err_msg;
464 const char *oid;
466 count = ARRAY_SIZE(_prefixmap_test_data);
467 for (i = 0; i < count; i++) {
468 oid = NULL;
469 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, _prefixmap_test_data[i].attid,
470 priv, &oid);
471 /* prepare error message */
472 err_msg = talloc_asprintf(priv, "dsdb_schema_pfm_oid_from_attid() failed with 0x%08X",
473 _prefixmap_test_data[i].attid);
474 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
475 /* verify result and returned ATTID */
476 torture_assert_werr_ok(tctx, werr, err_msg);
477 torture_assert(tctx, oid, "dsdb_schema_pfm_oid_from_attid() returned NULL OID!!!");
478 torture_assert_str_equal(tctx, oid, _prefixmap_test_data[i].oid, err_msg);
479 /* reclaim memory for prepared error message */
480 talloc_free(err_msg);
481 /* free memory for OID */
482 talloc_free(discard_const(oid));
485 return true;
489 * Tests dsdb_schema_pfm_oid_from_attid() for handling
490 * correctly different type of attid values.
491 * See: MS-ADTS, 3.1.1.2.6 ATTRTYP
493 static bool torture_drs_unit_pfm_oid_from_attid_check_attid(struct torture_context *tctx,
494 struct drsut_prefixmap_data *priv)
496 WERROR werr;
497 const char *oid;
499 /* Test with valid prefixMap attid */
500 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0x00010001, tctx, &oid);
501 torture_assert_werr_ok(tctx, werr, "Testing prefixMap type attid = 0x00010001");
503 /* Test with valid attid but invalid index */
504 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0x01110001, tctx, &oid);
505 torture_assert_werr_equal(tctx, werr, WERR_DS_NO_ATTRIBUTE_OR_VALUE,
506 "Testing invalid-index attid = 0x01110001");
508 /* Test with attid in msDS-IntId range */
509 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0x80000000, tctx, &oid);
510 torture_assert_werr_equal(tctx, werr, WERR_INVALID_PARAMETER,
511 "Testing msDS-IntId type attid = 0x80000000");
512 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0xBFFFFFFF, tctx, &oid);
513 torture_assert_werr_equal(tctx, werr, WERR_INVALID_PARAMETER,
514 "Testing msDS-IntId type attid = 0xBFFFFFFF");
516 /* Test with attid in RESERVED range */
517 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0xC0000000, tctx, &oid);
518 torture_assert_werr_equal(tctx, werr, WERR_INVALID_PARAMETER,
519 "Testing RESERVED type attid = 0xC0000000");
520 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0xFFFEFFFF, tctx, &oid);
521 torture_assert_werr_equal(tctx, werr, WERR_INVALID_PARAMETER,
522 "Testing RESERVED type attid = 0xFFFEFFFF");
524 /* Test with attid in INTERNAL range */
525 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0xFFFF0000, tctx, &oid);
526 torture_assert_werr_equal(tctx, werr, WERR_INVALID_PARAMETER,
527 "Testing INTERNAL type attid = 0xFFFF0000");
528 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0xFFFFFFFF, tctx, &oid);
529 torture_assert_werr_equal(tctx, werr, WERR_INVALID_PARAMETER,
530 "Testing INTERNAL type attid = 0xFFFFFFFF");
532 return true;
536 * Test Schema prefixMap conversions to/from drsuapi prefixMap
537 * representation.
539 static bool torture_drs_unit_pfm_to_from_drsuapi(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
541 WERROR werr;
542 const char *schema_info;
543 struct dsdb_schema_prefixmap *pfm;
544 struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
545 TALLOC_CTX *mem_ctx;
547 mem_ctx = talloc_new(tctx);
548 torture_assert(tctx, mem_ctx, "Unexpected: Have no memory!");
550 /* convert Schema_prefixMap to drsuapi_prefixMap */
551 werr = dsdb_drsuapi_pfm_from_schema_pfm(priv->pfm_full, priv->schi_default_str, mem_ctx, &ctr);
552 torture_assert_werr_ok(tctx, werr, "dsdb_drsuapi_pfm_from_schema_pfm() failed");
553 torture_assert(tctx, ctr && ctr->mappings, "drsuapi_prefixMap not constructed correctly");
554 torture_assert_int_equal(tctx, ctr->num_mappings, priv->pfm_full->length + 1,
555 "drs_mappings count does not match");
556 /* look for schema_info entry - it should be the last one */
557 schema_info = hex_encode_talloc(mem_ctx,
558 ctr->mappings[ctr->num_mappings - 1].oid.binary_oid,
559 ctr->mappings[ctr->num_mappings - 1].oid.length);
560 torture_assert_str_equal(tctx,
561 schema_info,
562 priv->schi_default_str,
563 "schema_info not stored correctly or not last entry");
565 /* compare schema_prefixMap and drsuapi_prefixMap */
566 werr = dsdb_schema_pfm_contains_drsuapi_pfm(priv->pfm_full, ctr);
567 torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_contains_drsuapi_pfm() failed");
569 /* convert back drsuapi_prefixMap to schema_prefixMap */
570 werr = dsdb_schema_pfm_from_drsuapi_pfm(ctr, true, mem_ctx, &pfm, &schema_info);
571 torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_from_drsuapi_pfm() failed");
572 torture_assert_str_equal(tctx, schema_info, priv->schi_default_str, "Fetched schema_info is different");
574 /* compare against the original */
575 if (!_torture_drs_pfm_compare_same(tctx, priv->pfm_full, pfm, true)) {
576 talloc_free(mem_ctx);
577 return false;
580 /* test conversion with partial drsuapi_prefixMap */
581 ctr->num_mappings--;
582 werr = dsdb_schema_pfm_from_drsuapi_pfm(ctr, false, mem_ctx, &pfm, NULL);
583 torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_from_drsuapi_pfm() failed");
584 /* compare against the original */
585 if (!_torture_drs_pfm_compare_same(tctx, priv->pfm_full, pfm, false)) {
586 talloc_free(mem_ctx);
587 return false;
590 talloc_free(mem_ctx);
591 return true;
596 * Test Schema prefixMap conversions to/from ldb_val
597 * blob representation.
599 static bool torture_drs_unit_pfm_to_from_ldb_val(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
601 WERROR werr;
602 const char *schema_info;
603 struct dsdb_schema *schema;
604 struct ldb_val pfm_ldb_val;
605 struct ldb_val schema_info_ldb_val;
606 TALLOC_CTX *mem_ctx;
608 mem_ctx = talloc_new(tctx);
609 torture_assert(tctx, mem_ctx, "Unexpected: Have no memory!");
611 schema = dsdb_new_schema(mem_ctx);
612 torture_assert(tctx, schema, "Unexpected: failed to allocate schema object");
614 /* set priv->pfm_full as prefixMap for new schema object */
615 schema->prefixmap = priv->pfm_full;
616 schema->schema_info = priv->schi_default_str;
618 /* convert schema_prefixMap to ldb_val blob */
619 werr = dsdb_get_oid_mappings_ldb(schema, mem_ctx, &pfm_ldb_val, &schema_info_ldb_val);
620 torture_assert_werr_ok(tctx, werr, "dsdb_get_oid_mappings_ldb() failed");
621 torture_assert(tctx, pfm_ldb_val.data && pfm_ldb_val.length,
622 "pfm_ldb_val not constructed correctly");
623 torture_assert(tctx, schema_info_ldb_val.data && schema_info_ldb_val.length,
624 "schema_info_ldb_val not constructed correctly");
625 /* look for schema_info entry - it should be the last one */
626 schema_info = hex_encode_talloc(mem_ctx,
627 schema_info_ldb_val.data,
628 schema_info_ldb_val.length);
629 torture_assert_str_equal(tctx,
630 schema_info,
631 priv->schi_default_str,
632 "schema_info not stored correctly or not last entry");
634 /* convert pfm_ldb_val back to schema_prefixMap */
635 schema->prefixmap = NULL;
636 schema->schema_info = NULL;
637 werr = dsdb_load_oid_mappings_ldb(schema, &pfm_ldb_val, &schema_info_ldb_val);
638 torture_assert_werr_ok(tctx, werr, "dsdb_load_oid_mappings_ldb() failed");
639 /* compare against the original */
640 if (!_torture_drs_pfm_compare_same(tctx, schema->prefixmap, priv->pfm_full, false)) {
641 talloc_free(mem_ctx);
642 return false;
645 talloc_free(mem_ctx);
646 return true;
650 * Test read/write in ldb implementation
652 static bool torture_drs_unit_pfm_read_write_ldb(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
654 WERROR werr;
655 struct dsdb_schema *schema;
656 struct dsdb_schema_prefixmap *pfm;
657 TALLOC_CTX *mem_ctx;
659 mem_ctx = talloc_new(tctx);
660 torture_assert(tctx, mem_ctx, "Unexpected: Have no memory!");
662 /* makeup a dsdb_schema to test with */
663 schema = dsdb_new_schema(mem_ctx);
664 torture_assert(tctx, schema, "Unexpected: failed to allocate schema object");
665 /* set priv->pfm_full as prefixMap for new schema object */
666 schema->prefixmap = priv->pfm_full;
667 schema->schema_info = priv->schi_default_str;
669 /* write prfixMap to ldb */
670 werr = dsdb_write_prefixes_from_schema_to_ldb(mem_ctx, priv->ldb_ctx, schema);
671 torture_assert_werr_ok(tctx, werr, "dsdb_write_prefixes_from_schema_to_ldb() failed");
673 /* read from ldb what we have written */
674 werr = dsdb_read_prefixes_from_ldb(priv->ldb_ctx, mem_ctx, &pfm);
675 torture_assert_werr_ok(tctx, werr, "dsdb_read_prefixes_from_ldb() failed");
677 /* compare data written/read */
678 if (!_torture_drs_pfm_compare_same(tctx, schema->prefixmap, priv->pfm_full, false)) {
679 torture_fail(tctx, "prefixMap read/write in LDB is not consistent");
682 talloc_free(mem_ctx);
684 return true;
688 * Test dsdb_create_prefix_mapping
690 static bool torture_drs_unit_dsdb_create_prefix_mapping(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
692 WERROR werr;
693 uint32_t i;
694 struct dsdb_schema *schema;
695 TALLOC_CTX *mem_ctx;
697 mem_ctx = talloc_new(tctx);
698 torture_assert(tctx, mem_ctx, "Unexpected: Have no memory!");
700 /* makeup a dsdb_schema to test with */
701 schema = dsdb_new_schema(mem_ctx);
702 torture_assert(tctx, schema, "Unexpected: failed to allocate schema object");
703 /* set priv->pfm_full as prefixMap for new schema object */
704 schema->schema_info = priv->schi_default_str;
705 werr = _drsut_prefixmap_new(_prefixmap_test_new_data, ARRAY_SIZE(_prefixmap_test_new_data),
706 schema, &schema->prefixmap);
707 torture_assert_werr_ok(tctx, werr, "_drsut_prefixmap_new() failed");
708 /* write prfixMap to ldb */
709 werr = dsdb_write_prefixes_from_schema_to_ldb(mem_ctx, priv->ldb_ctx, schema);
710 torture_assert_werr_ok(tctx, werr, "dsdb_write_prefixes_from_schema_to_ldb() failed");
712 for (i = 0; i < ARRAY_SIZE(_prefixmap_test_data); i++) {
713 struct dsdb_schema_prefixmap *pfm_ldb;
714 struct dsdb_schema_prefixmap *pfm_prev;
716 /* add ref to prefixMap so we can use it later */
717 pfm_prev = talloc_reference(schema, schema->prefixmap);
719 /* call dsdb_create_prefix_mapping() and check result accordingly */
720 werr = dsdb_create_prefix_mapping(priv->ldb_ctx, schema, _prefixmap_test_data[i].oid);
721 torture_assert_werr_ok(tctx, werr, "dsdb_create_prefix_mapping() failed");
723 /* verify pfm has been altered or not if needed */
724 if (_prefixmap_test_data[i].exists) {
725 torture_assert(tctx, pfm_prev == schema->prefixmap,
726 "schema->prefixmap has been reallocated!");
727 if (!_torture_drs_pfm_compare_same(tctx, pfm_prev, schema->prefixmap, true)) {
728 torture_fail(tctx, "schema->prefixmap has changed");
730 } else {
731 torture_assert(tctx, pfm_prev != schema->prefixmap,
732 "schema->prefixmap should be reallocated!");
733 if (_torture_drs_pfm_compare_same(tctx, pfm_prev, schema->prefixmap, true)) {
734 torture_fail(tctx, "schema->prefixmap should be changed");
738 /* read from ldb what we have written */
739 werr = dsdb_read_prefixes_from_ldb(priv->ldb_ctx, mem_ctx, &pfm_ldb);
740 torture_assert_werr_ok(tctx, werr, "dsdb_read_prefixes_from_ldb() failed");
741 /* compare data written/read */
742 if (!_torture_drs_pfm_compare_same(tctx, schema->prefixmap, pfm_ldb, true)) {
743 torture_fail(tctx, "schema->prefixmap and pfm in LDB are different");
745 /* free mem for pfm read from LDB */
746 talloc_free(pfm_ldb);
748 /* release prefixMap pointer */
749 talloc_unlink(schema, pfm_prev);
752 talloc_free(mem_ctx);
754 return true;
758 * Prepare temporary LDB and opens it
760 static bool torture_drs_unit_ldb_setup(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
762 int ldb_err;
763 char *ldb_url;
764 bool bret = true;
765 TALLOC_CTX* mem_ctx;
766 char *tempdir;
767 NTSTATUS status;
769 mem_ctx = talloc_new(priv);
771 status = torture_temp_dir(tctx, "drs_", &tempdir);
772 torture_assert_ntstatus_ok(tctx, status, "creating temp dir");
774 ldb_url = talloc_asprintf(priv, "%s/drs_test.ldb", tempdir);
776 /* create LDB */
777 priv->ldb_ctx = ldb_init(priv, tctx->ev);
778 ldb_err = ldb_connect(priv->ldb_ctx, ldb_url, 0, NULL);
779 torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE, "ldb_connect() failed");
781 /* set some schemaNamingContext */
782 ldb_err = ldb_set_opaque(priv->ldb_ctx,
783 "schemaNamingContext",
784 ldb_dn_new(priv->ldb_ctx, priv->ldb_ctx, "CN=Schema,CN=Config"));
785 torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE, "ldb_set_opaque() failed");
787 /* add prefixMap attribute so tested layer could work properly */
789 struct ldb_message *msg = ldb_msg_new(mem_ctx);
790 msg->dn = ldb_get_schema_basedn(priv->ldb_ctx);
791 ldb_err = ldb_msg_add_string(msg, "prefixMap", "prefixMap");
792 torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE,
793 "ldb_msg_add_empty() failed");
795 ldb_err = ldb_add(priv->ldb_ctx, msg);
796 torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE, "ldb_add() failed");
799 DONE:
800 talloc_free(mem_ctx);
801 return bret;
805 * Setup/Teardown for test case
807 static bool torture_drs_unit_prefixmap_setup(struct torture_context *tctx, struct drsut_prefixmap_data **_priv)
809 WERROR werr;
810 DATA_BLOB blob;
811 struct drsut_prefixmap_data *priv;
813 priv = *_priv = talloc_zero(tctx, struct drsut_prefixmap_data);
814 torture_assert(tctx, priv != NULL, "Not enough memory");
816 werr = _drsut_prefixmap_new(_prefixmap_test_new_data, ARRAY_SIZE(_prefixmap_test_new_data),
817 tctx, &priv->pfm_new);
818 torture_assert_werr_ok(tctx, werr, "failed to create pfm_new");
820 werr = _drsut_prefixmap_new(_prefixmap_full_map_data, ARRAY_SIZE(_prefixmap_full_map_data),
821 tctx, &priv->pfm_full);
822 torture_assert_werr_ok(tctx, werr, "failed to create pfm_test");
824 torture_assert(tctx, drsut_schemainfo_new(tctx, &priv->schi_default),
825 "drsut_schemainfo_new() failed");
827 werr = dsdb_blob_from_schema_info(priv->schi_default, priv, &blob);
828 torture_assert_werr_ok(tctx, werr, "dsdb_blob_from_schema_info() failed");
830 priv->schi_default_str = data_blob_hex_string_upper(priv, &blob);
832 /* create temporary LDB and populate with data */
833 if (!torture_drs_unit_ldb_setup(tctx, priv)) {
834 return false;
837 return true;
840 static bool torture_drs_unit_prefixmap_teardown(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
842 talloc_free(priv);
844 return true;
848 * Test case initialization for
849 * drs.unit.prefixMap
851 struct torture_tcase * torture_drs_unit_prefixmap(struct torture_suite *suite)
853 typedef bool (*pfn_setup)(struct torture_context *, void **);
854 typedef bool (*pfn_teardown)(struct torture_context *, void *);
855 typedef bool (*pfn_run)(struct torture_context *, void *);
857 struct torture_tcase * tc = torture_suite_add_tcase(suite, "prefixMap");
859 torture_tcase_set_fixture(tc,
860 (pfn_setup)torture_drs_unit_prefixmap_setup,
861 (pfn_teardown)torture_drs_unit_prefixmap_teardown);
863 tc->description = talloc_strdup(tc, "Unit tests for DRSUAPI::prefixMap implementation");
865 torture_tcase_add_simple_test(tc, "new", (pfn_run)torture_drs_unit_pfm_new);
867 torture_tcase_add_simple_test(tc, "make_attid_full_map", (pfn_run)torture_drs_unit_pfm_make_attid_full_map);
868 torture_tcase_add_simple_test(tc, "make_attid_small_map", (pfn_run)torture_drs_unit_pfm_make_attid_small_map);
870 torture_tcase_add_simple_test(tc, "attid_from_oid_full_map",
871 (pfn_run)torture_drs_unit_pfm_attid_from_oid_full_map);
872 torture_tcase_add_simple_test(tc, "attid_from_oid_empty_map",
873 (pfn_run)torture_drs_unit_pfm_attid_from_oid_base_map);
875 torture_tcase_add_simple_test(tc, "oid_from_attid_full_map", (pfn_run)torture_drs_unit_pfm_oid_from_attid);
876 torture_tcase_add_simple_test(tc, "oid_from_attid_check_attid",
877 (pfn_run)torture_drs_unit_pfm_oid_from_attid_check_attid);
879 torture_tcase_add_simple_test(tc, "pfm_to_from_drsuapi", (pfn_run)torture_drs_unit_pfm_to_from_drsuapi);
881 torture_tcase_add_simple_test(tc, "pfm_to_from_ldb_val", (pfn_run)torture_drs_unit_pfm_to_from_ldb_val);
883 torture_tcase_add_simple_test(tc, "pfm_read_write_ldb", (pfn_run)torture_drs_unit_pfm_read_write_ldb);
885 torture_tcase_add_simple_test(tc, "dsdb_create_prefix_mapping", (pfn_run)torture_drs_unit_dsdb_create_prefix_mapping);
887 return tc;