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/>.
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"
29 #include "librpc/ndr/libndr.h"
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 struct dsdb_schema_info
*schi_default
;
41 struct ldb_context
*ldb_ctx
;
45 * Test-oid data structure
47 struct drsut_pfm_oid_data
{
50 const char *oid_prefix
;
54 * Default prefixMap initialization data.
55 * This prefixMap is what dsdb_schema_pfm_new() should return.
56 * Based on: MS-DRSR, 5.16.4 ATTRTYP-to-OID Conversion
57 * procedure NewPrefixTable( )
59 static const struct drsut_pfm_oid_data _prefixmap_test_new_data
[] = {
60 {.id
=0x00000000, .bin_oid
="5504", .oid_prefix
="2.5.4"},
61 {.id
=0x00000001, .bin_oid
="5506", .oid_prefix
="2.5.6"},
62 {.id
=0x00000002, .bin_oid
="2A864886F7140102", .oid_prefix
="1.2.840.113556.1.2"},
63 {.id
=0x00000003, .bin_oid
="2A864886F7140103", .oid_prefix
="1.2.840.113556.1.3"},
64 {.id
=0x00000004, .bin_oid
="6086480165020201", .oid_prefix
="2.16.840.1.101.2.2.1"},
65 {.id
=0x00000005, .bin_oid
="6086480165020203", .oid_prefix
="2.16.840.1.101.2.2.3"},
66 {.id
=0x00000006, .bin_oid
="6086480165020105", .oid_prefix
="2.16.840.1.101.2.1.5"},
67 {.id
=0x00000007, .bin_oid
="6086480165020104", .oid_prefix
="2.16.840.1.101.2.1.4"},
68 {.id
=0x00000008, .bin_oid
="5505", .oid_prefix
="2.5.5"},
69 {.id
=0x00000009, .bin_oid
="2A864886F7140104", .oid_prefix
="1.2.840.113556.1.4"},
70 {.id
=0x0000000A, .bin_oid
="2A864886F7140105", .oid_prefix
="1.2.840.113556.1.5"},
71 {.id
=0x00000013, .bin_oid
="0992268993F22C64", .oid_prefix
="0.9.2342.19200300.100"},
72 {.id
=0x00000014, .bin_oid
="6086480186F84203", .oid_prefix
="2.16.840.1.113730.3"},
73 {.id
=0x00000015, .bin_oid
="0992268993F22C6401", .oid_prefix
="0.9.2342.19200300.100.1"},
74 {.id
=0x00000016, .bin_oid
="6086480186F8420301", .oid_prefix
="2.16.840.1.113730.3.1"},
75 {.id
=0x00000017, .bin_oid
="2A864886F7140105B658", .oid_prefix
="1.2.840.113556.1.5.7000"},
76 {.id
=0x00000018, .bin_oid
="5515", .oid_prefix
="2.5.21"},
77 {.id
=0x00000019, .bin_oid
="5512", .oid_prefix
="2.5.18"},
78 {.id
=0x0000001A, .bin_oid
="5514", .oid_prefix
="2.5.20"},
82 * Data to be used for creating full prefix map for testing.
83 * 'full-prefixMap' is based on what w2k8 returns as a prefixMap
84 * on clean installation - i.e. prefixMap for clean Schema
86 static const struct drsut_pfm_oid_data _prefixmap_full_map_data
[] = {
87 {.id
=0x00000000, .bin_oid
="0x5504", .oid_prefix
="2.5.4"},
88 {.id
=0x00000001, .bin_oid
="0x5506", .oid_prefix
="2.5.6"},
89 {.id
=0x00000002, .bin_oid
="0x2A864886F7140102", .oid_prefix
="1.2.840.113556.1.2"},
90 {.id
=0x00000003, .bin_oid
="0x2A864886F7140103", .oid_prefix
="1.2.840.113556.1.3"},
91 {.id
=0x00000004, .bin_oid
="0x6086480165020201", .oid_prefix
="2.16.840.1.101.2.2.1"},
92 {.id
=0x00000005, .bin_oid
="0x6086480165020203", .oid_prefix
="2.16.840.1.101.2.2.3"},
93 {.id
=0x00000006, .bin_oid
="0x6086480165020105", .oid_prefix
="2.16.840.1.101.2.1.5"},
94 {.id
=0x00000007, .bin_oid
="0x6086480165020104", .oid_prefix
="2.16.840.1.101.2.1.4"},
95 {.id
=0x00000008, .bin_oid
="0x5505", .oid_prefix
="2.5.5"},
96 {.id
=0x00000009, .bin_oid
="0x2A864886F7140104", .oid_prefix
="1.2.840.113556.1.4"},
97 {.id
=0x0000000a, .bin_oid
="0x2A864886F7140105", .oid_prefix
="1.2.840.113556.1.5"},
98 {.id
=0x00000013, .bin_oid
="0x0992268993F22C64", .oid_prefix
="0.9.2342.19200300.100"},
99 {.id
=0x00000014, .bin_oid
="0x6086480186F84203", .oid_prefix
="2.16.840.1.113730.3"},
100 {.id
=0x00000015, .bin_oid
="0x0992268993F22C6401", .oid_prefix
="0.9.2342.19200300.100.1"},
101 {.id
=0x00000016, .bin_oid
="0x6086480186F8420301", .oid_prefix
="2.16.840.1.113730.3.1"},
102 {.id
=0x00000017, .bin_oid
="0x2A864886F7140105B658", .oid_prefix
="1.2.840.113556.1.5.7000"},
103 {.id
=0x00000018, .bin_oid
="0x5515", .oid_prefix
="2.5.21"},
104 {.id
=0x00000019, .bin_oid
="0x5512", .oid_prefix
="2.5.18"},
105 {.id
=0x0000001a, .bin_oid
="0x5514", .oid_prefix
="2.5.20"},
106 {.id
=0x0000000b, .bin_oid
="0x2A864886F71401048204", .oid_prefix
="1.2.840.113556.1.4.260"},
107 {.id
=0x0000000c, .bin_oid
="0x2A864886F714010538", .oid_prefix
="1.2.840.113556.1.5.56"},
108 {.id
=0x0000000d, .bin_oid
="0x2A864886F71401048206", .oid_prefix
="1.2.840.113556.1.4.262"},
109 {.id
=0x0000000e, .bin_oid
="0x2A864886F714010539", .oid_prefix
="1.2.840.113556.1.5.57"},
110 {.id
=0x0000000f, .bin_oid
="0x2A864886F71401048207", .oid_prefix
="1.2.840.113556.1.4.263"},
111 {.id
=0x00000010, .bin_oid
="0x2A864886F71401053A", .oid_prefix
="1.2.840.113556.1.5.58"},
112 {.id
=0x00000011, .bin_oid
="0x2A864886F714010549", .oid_prefix
="1.2.840.113556.1.5.73"},
113 {.id
=0x00000012, .bin_oid
="0x2A864886F71401048231", .oid_prefix
="1.2.840.113556.1.4.305"},
114 {.id
=0x0000001b, .bin_oid
="0x2B060104018B3A6577", .oid_prefix
="1.3.6.1.4.1.1466.101.119"},
115 {.id
=0x0000001c, .bin_oid
="0x6086480186F8420302", .oid_prefix
="2.16.840.1.113730.3.2"},
116 {.id
=0x0000001d, .bin_oid
="0x2B06010401817A01", .oid_prefix
="1.3.6.1.4.1.250.1"},
117 {.id
=0x0000001e, .bin_oid
="0x2A864886F70D0109", .oid_prefix
="1.2.840.113549.1.9"},
118 {.id
=0x0000001f, .bin_oid
="0x0992268993F22C6404", .oid_prefix
="0.9.2342.19200300.100.4"},
119 {.id
=0x00000020, .bin_oid
="0x2A864886F714010617", .oid_prefix
="1.2.840.113556.1.6.23"},
120 {.id
=0x00000021, .bin_oid
="0x2A864886F71401061201", .oid_prefix
="1.2.840.113556.1.6.18.1"},
121 {.id
=0x00000022, .bin_oid
="0x2A864886F71401061202", .oid_prefix
="1.2.840.113556.1.6.18.2"},
122 {.id
=0x00000023, .bin_oid
="0x2A864886F71401060D03", .oid_prefix
="1.2.840.113556.1.6.13.3"},
123 {.id
=0x00000024, .bin_oid
="0x2A864886F71401060D04", .oid_prefix
="1.2.840.113556.1.6.13.4"},
124 {.id
=0x00000025, .bin_oid
="0x2B0601010101", .oid_prefix
="1.3.6.1.1.1.1"},
125 {.id
=0x00000026, .bin_oid
="0x2B0601010102", .oid_prefix
="1.3.6.1.1.1.2"},
126 {.id
=0x000003ed, .bin_oid
="0x2A864886F7140104B65866", .oid_prefix
="1.2.840.113556.1.4.7000.102"},
127 {.id
=0x00000428, .bin_oid
="0x2A864886F7140105B6583E", .oid_prefix
="1.2.840.113556.1.5.7000.62"},
128 {.id
=0x0000044c, .bin_oid
="0x2A864886F7140104B6586683", .oid_prefix
="1.2.840.113556.1.4.7000.102:0x83"},
129 {.id
=0x0000044f, .bin_oid
="0x2A864886F7140104B6586681", .oid_prefix
="1.2.840.113556.1.4.7000.102:0x81"},
130 {.id
=0x0000047d, .bin_oid
="0x2A864886F7140105B6583E81", .oid_prefix
="1.2.840.113556.1.5.7000.62:0x81"},
131 {.id
=0x00000561, .bin_oid
="0x2A864886F7140105B6583E83", .oid_prefix
="1.2.840.113556.1.5.7000.62:0x83"},
132 {.id
=0x000007d1, .bin_oid
="0x2A864886F71401061401", .oid_prefix
="1.2.840.113556.1.6.20.1"},
133 {.id
=0x000007e1, .bin_oid
="0x2A864886F71401061402", .oid_prefix
="1.2.840.113556.1.6.20.2"},
134 {.id
=0x00001b86, .bin_oid
="0x2A817A", .oid_prefix
="1.2.250"},
135 {.id
=0x00001c78, .bin_oid
="0x2A817A81", .oid_prefix
="1.2.250:0x81"},
136 {.id
=0x00001c7b, .bin_oid
="0x2A817A8180", .oid_prefix
="1.2.250:0x8180"},
141 * OID-to-ATTID mappings to be used for testing.
142 * An entry is marked as 'exists=true' if it exists in
143 * base prefixMap (_prefixmap_test_new_data)
145 static const struct {
150 } _prefixmap_test_data
[] = {
151 {.oid
="2.5.4.0", .id
=0x00000000, .attid
=0x000000, .exists
=true},
152 {.oid
="2.5.4.42", .id
=0x00000000, .attid
=0x00002a, .exists
=true},
153 {.oid
="1.2.840.113556.1.2.1", .id
=0x00000002, .attid
=0x020001, .exists
=true},
154 {.oid
="1.2.840.113556.1.2.13", .id
=0x00000002, .attid
=0x02000d, .exists
=true},
155 {.oid
="1.2.840.113556.1.2.281", .id
=0x00000002, .attid
=0x020119, .exists
=true},
156 {.oid
="1.2.840.113556.1.4.125", .id
=0x00000009, .attid
=0x09007d, .exists
=true},
157 {.oid
="1.2.840.113556.1.4.146", .id
=0x00000009, .attid
=0x090092, .exists
=true},
158 {.oid
="1.2.250.1", .id
=0x00001b86, .attid
=0x1b860001, .exists
=false},
159 {.oid
="1.2.250.16386", .id
=0x00001c78, .attid
=0x1c788002, .exists
=false},
160 {.oid
="1.2.250.2097154", .id
=0x00001c7b, .attid
=0x1c7b8002, .exists
=false},
165 * Creates dsdb_schema_prefixmap based on predefined data
167 static WERROR
_drsut_prefixmap_new(const struct drsut_pfm_oid_data
*_pfm_init_data
, uint32_t count
,
168 TALLOC_CTX
*mem_ctx
, struct dsdb_schema_prefixmap
**_pfm
)
171 struct dsdb_schema_prefixmap
*pfm
;
173 pfm
= talloc(mem_ctx
, struct dsdb_schema_prefixmap
);
174 W_ERROR_HAVE_NO_MEMORY(pfm
);
177 pfm
->prefixes
= talloc_array(pfm
, struct dsdb_schema_prefixmap_oid
, pfm
->length
);
178 if (!pfm
->prefixes
) {
180 return WERR_NOT_ENOUGH_MEMORY
;
183 for (i
= 0; i
< pfm
->length
; i
++) {
184 pfm
->prefixes
[i
].id
= _pfm_init_data
[i
].id
;
185 pfm
->prefixes
[i
].bin_oid
= strhex_to_data_blob(pfm
, _pfm_init_data
[i
].bin_oid
);
186 if (!pfm
->prefixes
[i
].bin_oid
.data
) {
188 return WERR_NOT_ENOUGH_MEMORY
;
198 * Compares two prefixMaps for being equal - same items on same indexes
200 static bool _torture_drs_pfm_compare_same(struct torture_context
*tctx
,
201 const struct dsdb_schema_prefixmap
*pfm_left
,
202 const struct dsdb_schema_prefixmap
*pfm_right
,
206 char *err_msg
= NULL
;
208 if (pfm_left
->length
!= pfm_right
->length
) {
209 err_msg
= talloc_asprintf(tctx
, "prefixMaps differ in size; left = %d, right = %d",
210 pfm_left
->length
, pfm_right
->length
);
214 for (i
= 0; i
< pfm_left
->length
; i
++) {
215 struct dsdb_schema_prefixmap_oid
*entry_left
= &pfm_left
->prefixes
[i
];
216 struct dsdb_schema_prefixmap_oid
*entry_right
= &pfm_right
->prefixes
[i
];
218 if (entry_left
->id
!= entry_right
->id
) {
219 err_msg
= talloc_asprintf(tctx
, "Different IDs for index=%d", i
);
222 if (data_blob_cmp(&entry_left
->bin_oid
, &entry_right
->bin_oid
)) {
223 err_msg
= talloc_asprintf(tctx
, "Different bin_oid for index=%d", i
);
232 torture_comment(tctx
, "_torture_drs_pfm_compare_same: %s", err_msg
);
234 talloc_free(err_msg
);
240 * Tests dsdb_schema_pfm_new()
242 static bool torture_drs_unit_pfm_new(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
247 struct dsdb_schema_prefixmap
*pfm
= NULL
;
249 mem_ctx
= talloc_new(priv
);
251 /* create new prefix map */
252 werr
= dsdb_schema_pfm_new(mem_ctx
, &pfm
);
253 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_pfm_new() failed!");
254 torture_assert(tctx
, pfm
!= NULL
, "NULL prefixMap created!");
255 torture_assert(tctx
, pfm
->length
> 0, "Empty prefixMap created!");
256 torture_assert(tctx
, pfm
->prefixes
!= NULL
, "No prefixes for newly created prefixMap!");
258 /* compare newly created prefixMap with template one */
259 bret
= _torture_drs_pfm_compare_same(tctx
, priv
->pfm_new
, pfm
, false);
261 talloc_free(mem_ctx
);
267 * Tests dsdb_schema_pfm_make_attid() using full prefixMap.
268 * In this test we know exactly which ATTID and prefixMap->ID
269 * should be returned, i.e. no prefixMap entries should be added.
271 static bool torture_drs_unit_pfm_make_attid_full_map(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
278 count
= ARRAY_SIZE(_prefixmap_test_data
);
279 for (i
= 0; i
< count
; i
++) {
280 werr
= dsdb_schema_pfm_make_attid(priv
->pfm_full
, _prefixmap_test_data
[i
].oid
, &attid
);
281 /* prepare error message */
282 err_msg
= talloc_asprintf(priv
, "dsdb_schema_pfm_make_attid() failed with %s",
283 _prefixmap_test_data
[i
].oid
);
284 torture_assert(tctx
, err_msg
, "Unexpected: Have no memory!");
285 /* verify result and returned ATTID */
286 torture_assert_werr_ok(tctx
, werr
, err_msg
);
287 torture_assert_int_equal(tctx
, attid
, _prefixmap_test_data
[i
].attid
, err_msg
);
288 /* reclaim memory for prepared error message */
289 talloc_free(err_msg
);
296 * Tests dsdb_schema_pfm_make_attid() using initially small prefixMap.
297 * In this test we don't know exactly which ATTID and prefixMap->ID
298 * should be returned, but we can verify lo-word of ATTID.
299 * This test verifies implementation branch when a new
300 * prefix should be added into prefixMap.
302 static bool torture_drs_unit_pfm_make_attid_small_map(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
307 uint32_t attid
, attid_2
;
309 struct dsdb_schema_prefixmap
*pfm
= NULL
;
312 mem_ctx
= talloc_new(priv
);
314 /* create new prefix map */
315 werr
= dsdb_schema_pfm_new(mem_ctx
, &pfm
);
316 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_pfm_new() failed!");
318 /* make some ATTIDs and check result */
319 for (i
= 0; i
< ARRAY_SIZE(_prefixmap_test_data
); i
++) {
320 werr
= dsdb_schema_pfm_make_attid(pfm
, _prefixmap_test_data
[i
].oid
, &attid
);
322 /* prepare error message */
323 err_msg
= talloc_asprintf(mem_ctx
, "dsdb_schema_pfm_make_attid() failed with %s",
324 _prefixmap_test_data
[i
].oid
);
325 torture_assert(tctx
, err_msg
, "Unexpected: Have no memory!");
327 /* verify result and returned ATTID */
328 torture_assert_werr_ok(tctx
, werr
, err_msg
);
329 /* verify ATTID lo-word */
330 torture_assert_int_equal(tctx
, attid
& 0xFFFF, _prefixmap_test_data
[i
].attid
& 0xFFFF, err_msg
);
332 /* try again, this time verify for whole ATTID */
333 werr
= dsdb_schema_pfm_make_attid(pfm
, _prefixmap_test_data
[i
].oid
, &attid_2
);
334 torture_assert_werr_ok(tctx
, werr
, err_msg
);
335 torture_assert_int_equal(tctx
, attid_2
, attid
, err_msg
);
337 /* reclaim memory for prepared error message */
338 talloc_free(err_msg
);
340 /* check there is such an index in modified prefixMap */
342 for (j
= 0; j
< pfm
->length
; j
++) {
343 if (pfm
->prefixes
[j
].id
== idx
)
346 if (j
>= pfm
->length
) {
347 torture_result(tctx
, TORTURE_FAIL
, __location__
": No prefix for ATTID=0x%08X", attid
);
353 talloc_free(mem_ctx
);
359 * Tests dsdb_schema_pfm_attid_from_oid() using full prefixMap.
360 * In this test we know exactly which ATTID and prefixMap->ID
361 * should be returned- dsdb_schema_pfm_attid_from_oid() should succeed.
363 static bool torture_drs_unit_pfm_attid_from_oid_full_map(struct torture_context
*tctx
,
364 struct drsut_prefixmap_data
*priv
)
371 count
= ARRAY_SIZE(_prefixmap_test_data
);
372 for (i
= 0; i
< count
; i
++) {
373 werr
= dsdb_schema_pfm_attid_from_oid(priv
->pfm_full
,
374 _prefixmap_test_data
[i
].oid
,
376 /* prepare error message */
377 err_msg
= talloc_asprintf(priv
, "dsdb_schema_pfm_attid_from_oid() failed with %s",
378 _prefixmap_test_data
[i
].oid
);
379 torture_assert(tctx
, err_msg
, "Unexpected: Have no memory!");
380 /* verify result and returned ATTID */
381 torture_assert_werr_ok(tctx
, werr
, err_msg
);
382 torture_assert_int_equal(tctx
, attid
, _prefixmap_test_data
[i
].attid
, err_msg
);
383 /* reclaim memory for prepared error message */
384 talloc_free(err_msg
);
391 * Tests dsdb_schema_pfm_attid_from_oid() using base (initial) prefixMap.
392 * dsdb_schema_pfm_attid_from_oid() should fail when testing with OID
393 * that are not already in the prefixMap.
395 static bool torture_drs_unit_pfm_attid_from_oid_base_map(struct torture_context
*tctx
,
396 struct drsut_prefixmap_data
*priv
)
402 struct dsdb_schema_prefixmap
*pfm
= NULL
;
403 struct dsdb_schema_prefixmap pfm_prev
;
406 mem_ctx
= talloc_new(priv
);
407 torture_assert(tctx
, mem_ctx
, "Unexpected: Have no memory!");
409 /* create new prefix map */
410 werr
= dsdb_schema_pfm_new(mem_ctx
, &pfm
);
411 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_pfm_new() failed!");
413 /* keep initial pfm around for testing */
415 pfm_prev
.prefixes
= talloc_reference(mem_ctx
, pfm
->prefixes
);
417 /* get some ATTIDs and check result */
418 for (i
= 0; i
< ARRAY_SIZE(_prefixmap_test_data
); i
++) {
419 werr
= dsdb_schema_pfm_attid_from_oid(pfm
, _prefixmap_test_data
[i
].oid
, &attid
);
421 /* prepare error message */
422 err_msg
= talloc_asprintf(mem_ctx
,
423 "dsdb_schema_pfm_attid_from_oid() failed for %s",
424 _prefixmap_test_data
[i
].oid
);
425 torture_assert(tctx
, err_msg
, "Unexpected: Have no memory!");
428 /* verify pfm hasn't been altered */
429 if (_prefixmap_test_data
[i
].exists
) {
430 /* should succeed and return valid ATTID */
431 torture_assert_werr_ok(tctx
, werr
, err_msg
);
433 torture_assert_int_equal(tctx
,
434 attid
, _prefixmap_test_data
[i
].attid
,
438 torture_assert_werr_equal(tctx
, werr
, WERR_NOT_FOUND
, err_msg
);
441 /* prefixMap should never be changed */
442 if (!_torture_drs_pfm_compare_same(tctx
, &pfm_prev
, pfm
, true)) {
443 torture_fail(tctx
, "schema->prefixmap has changed");
446 /* reclaim memory for prepared error message */
447 talloc_free(err_msg
);
450 talloc_free(mem_ctx
);
456 * Tests dsdb_schema_pfm_oid_from_attid() using full prefixMap.
458 static bool torture_drs_unit_pfm_oid_from_attid(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
465 count
= ARRAY_SIZE(_prefixmap_test_data
);
466 for (i
= 0; i
< count
; i
++) {
468 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, _prefixmap_test_data
[i
].attid
,
470 /* prepare error message */
471 err_msg
= talloc_asprintf(priv
, "dsdb_schema_pfm_oid_from_attid() failed with 0x%08X",
472 _prefixmap_test_data
[i
].attid
);
473 torture_assert(tctx
, err_msg
, "Unexpected: Have no memory!");
474 /* verify result and returned ATTID */
475 torture_assert_werr_ok(tctx
, werr
, err_msg
);
476 torture_assert(tctx
, oid
, "dsdb_schema_pfm_oid_from_attid() returned NULL OID!!!");
477 torture_assert_str_equal(tctx
, oid
, _prefixmap_test_data
[i
].oid
, err_msg
);
478 /* reclaim memory for prepared error message */
479 talloc_free(err_msg
);
480 /* free memory for OID */
481 talloc_free(discard_const(oid
));
488 * Tests dsdb_schema_pfm_oid_from_attid() for handling
489 * correctly different type of attid values.
490 * See: MS-ADTS, 3.1.1.2.6 ATTRTYP
492 static bool torture_drs_unit_pfm_oid_from_attid_check_attid(struct torture_context
*tctx
,
493 struct drsut_prefixmap_data
*priv
)
498 /* Test with valid prefixMap attid */
499 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, 0x00010001, tctx
, &oid
);
500 torture_assert_werr_ok(tctx
, werr
, "Testing prefixMap type attid = 0x00010001");
502 /* Test with valid attid but invalid index */
503 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, 0x01110001, tctx
, &oid
);
504 torture_assert_werr_equal(tctx
, werr
, WERR_DS_NO_ATTRIBUTE_OR_VALUE
,
505 "Testing invalid-index attid = 0x01110001");
507 /* Test with attid in msDS-IntId range */
508 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, 0x80000000, tctx
, &oid
);
509 torture_assert_werr_equal(tctx
, werr
, WERR_INVALID_PARAMETER
,
510 "Testing msDS-IntId type attid = 0x80000000");
511 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, 0xBFFFFFFF, tctx
, &oid
);
512 torture_assert_werr_equal(tctx
, werr
, WERR_INVALID_PARAMETER
,
513 "Testing msDS-IntId type attid = 0xBFFFFFFF");
515 /* Test with attid in RESERVED range */
516 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, 0xC0000000, tctx
, &oid
);
517 torture_assert_werr_equal(tctx
, werr
, WERR_INVALID_PARAMETER
,
518 "Testing RESERVED type attid = 0xC0000000");
519 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, 0xFFFEFFFF, tctx
, &oid
);
520 torture_assert_werr_equal(tctx
, werr
, WERR_INVALID_PARAMETER
,
521 "Testing RESERVED type attid = 0xFFFEFFFF");
523 /* Test with attid in INTERNAL range */
524 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, 0xFFFF0000, tctx
, &oid
);
525 torture_assert_werr_equal(tctx
, werr
, WERR_INVALID_PARAMETER
,
526 "Testing INTERNAL type attid = 0xFFFF0000");
527 werr
= dsdb_schema_pfm_oid_from_attid(priv
->pfm_full
, 0xFFFFFFFF, tctx
, &oid
);
528 torture_assert_werr_equal(tctx
, werr
, WERR_INVALID_PARAMETER
,
529 "Testing INTERNAL type attid = 0xFFFFFFFF");
535 * Test Schema prefixMap conversions to/from drsuapi prefixMap
538 static bool torture_drs_unit_pfm_to_from_drsuapi(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
541 struct dsdb_schema_info
*schema_info
;
542 DATA_BLOB schema_info_blob
;
543 struct dsdb_schema_prefixmap
*pfm
;
544 struct drsuapi_DsReplicaOIDMapping_Ctr
*ctr
;
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
, 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_blob
= data_blob_const(ctr
->mappings
[ctr
->num_mappings
- 1].oid
.binary_oid
,
558 ctr
->mappings
[ctr
->num_mappings
- 1].oid
.length
);
559 werr
= dsdb_schema_info_from_blob(&schema_info_blob
, tctx
, &schema_info
);
560 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_info_from_blob failed");
561 torture_assert_int_equal(tctx
, schema_info
->revision
, priv
->schi_default
->revision
,
562 "schema_info (revision) not stored correctly or not last entry");
563 torture_assert(tctx
, GUID_equal(&schema_info
->invocation_id
, &priv
->schi_default
->invocation_id
),
564 "schema_info (invocation_id) not stored correctly or not last entry");
566 /* compare schema_prefixMap and drsuapi_prefixMap */
567 werr
= dsdb_schema_pfm_contains_drsuapi_pfm(priv
->pfm_full
, ctr
);
568 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_pfm_contains_drsuapi_pfm() failed");
570 /* convert back drsuapi_prefixMap to schema_prefixMap */
571 werr
= dsdb_schema_pfm_from_drsuapi_pfm(ctr
, true, mem_ctx
, &pfm
, &schema_info
);
572 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_pfm_from_drsuapi_pfm() failed");
573 torture_assert_int_equal(tctx
, schema_info
->revision
, priv
->schi_default
->revision
,
574 "Fetched schema_info is different (revision)");
575 torture_assert(tctx
, GUID_equal(&schema_info
->invocation_id
, &priv
->schi_default
->invocation_id
),
576 "Fetched schema_info is different (invocation_id)");
578 /* compare against the original */
579 if (!_torture_drs_pfm_compare_same(tctx
, priv
->pfm_full
, pfm
, true)) {
580 talloc_free(mem_ctx
);
584 /* test conversion with partial drsuapi_prefixMap */
586 werr
= dsdb_schema_pfm_from_drsuapi_pfm(ctr
, false, mem_ctx
, &pfm
, NULL
);
587 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_pfm_from_drsuapi_pfm() failed");
588 /* compare against the original */
589 if (!_torture_drs_pfm_compare_same(tctx
, priv
->pfm_full
, pfm
, false)) {
590 talloc_free(mem_ctx
);
594 talloc_free(mem_ctx
);
600 * Test Schema prefixMap conversions to/from ldb_val
601 * blob representation.
603 static bool torture_drs_unit_pfm_to_from_ldb_val(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
606 struct dsdb_schema
*schema
;
607 struct ldb_val pfm_ldb_val
;
608 struct ldb_val schema_info_ldb_val
;
611 mem_ctx
= talloc_new(tctx
);
612 torture_assert(tctx
, mem_ctx
, "Unexpected: Have no memory!");
614 schema
= dsdb_new_schema(mem_ctx
);
615 torture_assert(tctx
, schema
, "Unexpected: failed to allocate schema object");
617 /* set priv->pfm_full as prefixMap for new schema object */
618 schema
->prefixmap
= priv
->pfm_full
;
619 schema
->schema_info
= priv
->schi_default
;
621 /* convert schema_prefixMap to ldb_val blob */
622 werr
= dsdb_get_oid_mappings_ldb(schema
, mem_ctx
, &pfm_ldb_val
, &schema_info_ldb_val
);
623 torture_assert_werr_ok(tctx
, werr
, "dsdb_get_oid_mappings_ldb() failed");
624 torture_assert(tctx
, pfm_ldb_val
.data
&& pfm_ldb_val
.length
,
625 "pfm_ldb_val not constructed correctly");
626 torture_assert(tctx
, schema_info_ldb_val
.data
&& schema_info_ldb_val
.length
,
627 "schema_info_ldb_val not constructed correctly");
629 /* convert pfm_ldb_val back to schema_prefixMap */
630 schema
->prefixmap
= NULL
;
631 schema
->schema_info
= NULL
;
632 werr
= dsdb_load_oid_mappings_ldb(schema
, &pfm_ldb_val
, &schema_info_ldb_val
);
633 torture_assert_werr_ok(tctx
, werr
, "dsdb_load_oid_mappings_ldb() failed");
634 /* compare against the original */
635 if (!_torture_drs_pfm_compare_same(tctx
, schema
->prefixmap
, priv
->pfm_full
, false)) {
636 talloc_free(mem_ctx
);
639 torture_assert_int_equal(tctx
, schema
->schema_info
->revision
, priv
->schi_default
->revision
,
640 "Fetched schema_info is different (revision)");
641 torture_assert(tctx
, GUID_equal(&schema
->schema_info
->invocation_id
, &priv
->schi_default
->invocation_id
),
642 "Fetched schema_info is different (invocation_id)");
644 talloc_free(mem_ctx
);
649 * Test read/write in ldb implementation
651 static bool torture_drs_unit_pfm_read_write_ldb(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
654 struct dsdb_schema
*schema
;
655 struct dsdb_schema_prefixmap
*pfm
;
658 mem_ctx
= talloc_new(tctx
);
659 torture_assert(tctx
, mem_ctx
, "Unexpected: Have no memory!");
661 /* makeup a dsdb_schema to test with */
662 schema
= dsdb_new_schema(mem_ctx
);
663 torture_assert(tctx
, schema
, "Unexpected: failed to allocate schema object");
664 /* set priv->pfm_full as prefixMap for new schema object */
665 schema
->prefixmap
= priv
->pfm_full
;
666 schema
->schema_info
= priv
->schi_default
;
668 /* write prfixMap to ldb */
669 werr
= dsdb_write_prefixes_from_schema_to_ldb(mem_ctx
, priv
->ldb_ctx
, schema
);
670 torture_assert_werr_ok(tctx
, werr
, "dsdb_write_prefixes_from_schema_to_ldb() failed");
672 /* read from ldb what we have written */
673 werr
= dsdb_read_prefixes_from_ldb(priv
->ldb_ctx
, mem_ctx
, &pfm
);
674 torture_assert_werr_ok(tctx
, werr
, "dsdb_read_prefixes_from_ldb() failed");
676 /* compare data written/read */
677 if (!_torture_drs_pfm_compare_same(tctx
, schema
->prefixmap
, priv
->pfm_full
, false)) {
678 torture_fail(tctx
, "prefixMap read/write in LDB is not consistent");
681 talloc_free(mem_ctx
);
687 * Test dsdb_create_prefix_mapping
689 static bool torture_drs_unit_dsdb_create_prefix_mapping(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
693 struct dsdb_schema
*schema
;
695 struct dsdb_schema_prefixmap
*pfm_ldb
= NULL
;
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
;
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 /* read from ldb what we have written */
713 werr
= dsdb_read_prefixes_from_ldb(priv
->ldb_ctx
, mem_ctx
, &pfm_ldb
);
714 torture_assert_werr_ok(tctx
, werr
, "dsdb_read_prefixes_from_ldb() failed");
715 /* compare data written/read */
716 if (!_torture_drs_pfm_compare_same(tctx
, schema
->prefixmap
, pfm_ldb
, true)) {
717 torture_fail(tctx
, "pfm in LDB is different");
719 TALLOC_FREE(pfm_ldb
);
721 for (i
= 0; i
< ARRAY_SIZE(_prefixmap_test_data
); i
++) {
722 struct dsdb_schema_prefixmap
*pfm_prev
;
723 struct dsdb_schema_prefixmap
*pfm_new
;
725 pfm_prev
= schema
->prefixmap
;
727 pfm_new
= dsdb_schema_pfm_copy_shallow(schema
, pfm_prev
);
728 torture_assert(tctx
, pfm_new
!= NULL
, "dsdb_schema_pfm_copy_shallow() failed");
730 if (!_prefixmap_test_data
[i
].exists
) {
733 werr
= dsdb_schema_pfm_make_attid(pfm_new
,
734 _prefixmap_test_data
[i
].oid
,
736 torture_assert_werr_ok(tctx
, werr
, "dsdb_schema_pfm_make_attid() failed");
739 /* call dsdb_create_prefix_mapping() and check result accordingly */
740 werr
= dsdb_create_prefix_mapping(priv
->ldb_ctx
, schema
, _prefixmap_test_data
[i
].oid
);
741 torture_assert_werr_ok(tctx
, werr
, "dsdb_create_prefix_mapping() failed");
744 * The prefix should not change, only on reload
746 torture_assert(tctx
, pfm_prev
== schema
->prefixmap
,
747 "schema->prefixmap has been reallocated!");
748 if (!_torture_drs_pfm_compare_same(tctx
, pfm_prev
, schema
->prefixmap
, true)) {
749 torture_fail(tctx
, "schema->prefixmap has changed");
752 /* read from ldb what we have written */
753 werr
= dsdb_read_prefixes_from_ldb(priv
->ldb_ctx
, mem_ctx
, &pfm_ldb
);
754 torture_assert_werr_ok(tctx
, werr
, "dsdb_read_prefixes_from_ldb() failed");
755 /* compare data written/read */
756 if (!_torture_drs_pfm_compare_same(tctx
, pfm_new
, pfm_ldb
, true)) {
757 torture_fail(tctx
, talloc_asprintf(tctx
, "%u: pfm in LDB is different", i
));
759 /* free mem for pfm read from LDB */
760 TALLOC_FREE(pfm_ldb
);
762 /* prepare for the next round */
763 schema
->prefixmap
= pfm_new
;
766 talloc_free(mem_ctx
);
772 * Prepare temporary LDB and opens it
774 static bool torture_drs_unit_ldb_setup(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
783 mem_ctx
= talloc_new(priv
);
785 status
= torture_temp_dir(tctx
, "drs_", &tempdir
);
786 torture_assert_ntstatus_ok(tctx
, status
, "creating temp dir");
788 ldb_url
= talloc_asprintf(priv
, "%s/drs_test.ldb", tempdir
);
791 priv
->ldb_ctx
= ldb_init(priv
, tctx
->ev
);
792 ldb_err
= ldb_connect(priv
->ldb_ctx
, ldb_url
, 0, NULL
);
793 torture_assert_int_equal_goto(tctx
, ldb_err
, LDB_SUCCESS
, bret
, DONE
, "ldb_connect() failed");
795 /* set some schemaNamingContext */
796 ldb_err
= ldb_set_opaque(priv
->ldb_ctx
,
797 "schemaNamingContext",
798 ldb_dn_new(priv
->ldb_ctx
, priv
->ldb_ctx
, "CN=Schema,CN=Config"));
799 torture_assert_int_equal_goto(tctx
, ldb_err
, LDB_SUCCESS
, bret
, DONE
, "ldb_set_opaque() failed");
801 /* add prefixMap attribute so tested layer could work properly */
803 struct ldb_message
*msg
= ldb_msg_new(mem_ctx
);
804 msg
->dn
= ldb_get_schema_basedn(priv
->ldb_ctx
);
805 ldb_err
= ldb_msg_add_string(msg
, "prefixMap", "prefixMap");
806 torture_assert_int_equal_goto(tctx
, ldb_err
, LDB_SUCCESS
, bret
, DONE
,
807 "ldb_msg_add_string() failed");
809 ldb_err
= ldb_add(priv
->ldb_ctx
, msg
);
810 torture_assert_int_equal_goto(tctx
, ldb_err
, LDB_SUCCESS
, bret
, DONE
, "ldb_add() failed");
814 talloc_free(mem_ctx
);
819 * Setup/Teardown for test case
821 static bool torture_drs_unit_prefixmap_setup(struct torture_context
*tctx
, struct drsut_prefixmap_data
**_priv
)
825 struct drsut_prefixmap_data
*priv
;
827 priv
= *_priv
= talloc_zero(tctx
, struct drsut_prefixmap_data
);
828 torture_assert(tctx
, priv
!= NULL
, "Not enough memory");
830 werr
= _drsut_prefixmap_new(_prefixmap_test_new_data
, ARRAY_SIZE(_prefixmap_test_new_data
),
831 tctx
, &priv
->pfm_new
);
832 torture_assert_werr_ok(tctx
, werr
, "failed to create pfm_new");
834 werr
= _drsut_prefixmap_new(_prefixmap_full_map_data
, ARRAY_SIZE(_prefixmap_full_map_data
),
835 tctx
, &priv
->pfm_full
);
836 torture_assert_werr_ok(tctx
, werr
, "failed to create pfm_test");
838 torture_assert(tctx
, drsut_schemainfo_new(tctx
, &priv
->schi_default
),
839 "drsut_schemainfo_new() failed");
841 werr
= dsdb_blob_from_schema_info(priv
->schi_default
, priv
, &blob
);
842 torture_assert_werr_ok(tctx
, werr
, "dsdb_blob_from_schema_info() failed");
844 /* create temporary LDB and populate with data */
845 if (!torture_drs_unit_ldb_setup(tctx
, priv
)) {
852 static bool torture_drs_unit_prefixmap_teardown(struct torture_context
*tctx
, struct drsut_prefixmap_data
*priv
)
860 * Test case initialization for
863 struct torture_tcase
* torture_drs_unit_prefixmap(struct torture_suite
*suite
)
865 typedef bool (*pfn_setup
)(struct torture_context
*, void **);
866 typedef bool (*pfn_teardown
)(struct torture_context
*, void *);
867 typedef bool (*pfn_run
)(struct torture_context
*, void *);
869 struct torture_tcase
* tc
= torture_suite_add_tcase(suite
, "prefixMap");
871 torture_tcase_set_fixture(tc
,
872 (pfn_setup
)torture_drs_unit_prefixmap_setup
,
873 (pfn_teardown
)torture_drs_unit_prefixmap_teardown
);
875 tc
->description
= talloc_strdup(tc
, "Unit tests for DRSUAPI::prefixMap implementation");
877 torture_tcase_add_simple_test(tc
, "new", (pfn_run
)torture_drs_unit_pfm_new
);
879 torture_tcase_add_simple_test(tc
, "make_attid_full_map", (pfn_run
)torture_drs_unit_pfm_make_attid_full_map
);
880 torture_tcase_add_simple_test(tc
, "make_attid_small_map", (pfn_run
)torture_drs_unit_pfm_make_attid_small_map
);
882 torture_tcase_add_simple_test(tc
, "attid_from_oid_full_map",
883 (pfn_run
)torture_drs_unit_pfm_attid_from_oid_full_map
);
884 torture_tcase_add_simple_test(tc
, "attid_from_oid_empty_map",
885 (pfn_run
)torture_drs_unit_pfm_attid_from_oid_base_map
);
887 torture_tcase_add_simple_test(tc
, "oid_from_attid_full_map", (pfn_run
)torture_drs_unit_pfm_oid_from_attid
);
888 torture_tcase_add_simple_test(tc
, "oid_from_attid_check_attid",
889 (pfn_run
)torture_drs_unit_pfm_oid_from_attid_check_attid
);
891 torture_tcase_add_simple_test(tc
, "pfm_to_from_drsuapi", (pfn_run
)torture_drs_unit_pfm_to_from_drsuapi
);
893 torture_tcase_add_simple_test(tc
, "pfm_to_from_ldb_val", (pfn_run
)torture_drs_unit_pfm_to_from_ldb_val
);
895 torture_tcase_add_simple_test(tc
, "pfm_read_write_ldb", (pfn_run
)torture_drs_unit_pfm_read_write_ldb
);
897 torture_tcase_add_simple_test(tc
, "dsdb_create_prefix_mapping", (pfn_run
)torture_drs_unit_dsdb_create_prefix_mapping
);