16d8298ef25619b31b051f77d7e26e3e2c7dd869
[sfrench/samba-autobuild/.git] / source4 / torture / drs / unit / prefixmap_tests.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    DRSUAPI prefixMap unit tests
5
6    Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2009
7
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.
12
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.
17
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/>.
20 */
21
22 #include "includes.h"
23 #include "torture/smbtorture.h"
24 #include "torture/rpc/drsuapi.h"
25 #include "dsdb/samdb/samdb.h"
26
27
28 /**
29  * Private data to be shared among all test in Test case
30  */
31 struct drsut_prefixmap_data {
32         struct dsdb_schema_prefixmap *pfm_new;
33         struct dsdb_schema_prefixmap *pfm_full;
34 };
35
36 /**
37  * Test-oid data structure
38  */
39 struct drsut_pfm_oid_data {
40         uint32_t        id;
41         const char      *bin_oid;
42         const char      *oid_prefix;
43 };
44
45 /**
46  * Default prefixMap initialization data
47  */
48 static const struct drsut_pfm_oid_data _prefixmap_test_new_data[] = {
49         {.id=0x00000000, .bin_oid="5504",                 .oid_prefix="2.5.4"},
50         {.id=0x00000001, .bin_oid="5506",                 .oid_prefix="2.5.6"},
51         {.id=0x00000002, .bin_oid="2A864886F7140102",     .oid_prefix="1.2.840.113556.1.2"},
52         {.id=0x00000003, .bin_oid="2A864886F7140103",     .oid_prefix="1.2.840.113556.1.3"},
53         {.id=0x00000004, .bin_oid="6086480165020201",     .oid_prefix="2.16.840.1.101.2.2.1"},
54         {.id=0x00000005, .bin_oid="6086480165020203",     .oid_prefix="2.16.840.1.101.2.2.3"},
55         {.id=0x00000006, .bin_oid="6086480165020105",     .oid_prefix="2.16.840.1.101.2.1.5"},
56         {.id=0x00000007, .bin_oid="6086480165020104",     .oid_prefix="2.16.840.1.101.2.1.4"},
57         {.id=0x00000008, .bin_oid="5505",                 .oid_prefix="2.5.5"},
58         {.id=0x00000009, .bin_oid="2A864886F7140104",     .oid_prefix="1.2.840.113556.1.4"},
59         {.id=0x0000000A, .bin_oid="2A864886F7140105",     .oid_prefix="1.2.840.113556.1.5"},
60         {.id=0x00000013, .bin_oid="0992268993F22C64",     .oid_prefix="0.9.2342.19200300.100"},
61         {.id=0x00000014, .bin_oid="6086480186F84203",     .oid_prefix="2.16.840.1.113730.3"},
62         {.id=0x00000015, .bin_oid="0992268993F22C6401",   .oid_prefix="0.9.2342.19200300.100.1"},
63         {.id=0x00000016, .bin_oid="6086480186F8420301",   .oid_prefix="2.16.840.1.113730.3.1"},
64         {.id=0x00000017, .bin_oid="2A864886F7140105B658", .oid_prefix="1.2.840.113556.1.5.7000"},
65         {.id=0x00000018, .bin_oid="5515",                 .oid_prefix="2.5.21"},
66         {.id=0x00000019, .bin_oid="5512",                 .oid_prefix="2.5.18"},
67         {.id=0x0000001A, .bin_oid="5514",                 .oid_prefix="2.5.20"},
68 };
69
70 /**
71  * Data to be used for creating full prefix map for testing
72  */
73 static const struct drsut_pfm_oid_data _prefixmap_full_map_data[] = {
74         {.id=0x00000000, .bin_oid="0x5504",                     .oid_prefix="2.5.4"},
75         {.id=0x00000001, .bin_oid="0x5506",                     .oid_prefix="2.5.6"},
76         {.id=0x00000002, .bin_oid="0x2A864886F7140102",         .oid_prefix="1.2.840.113556.1.2"},
77         {.id=0x00000003, .bin_oid="0x2A864886F7140103",         .oid_prefix="1.2.840.113556.1.3"},
78         {.id=0x00000004, .bin_oid="0x6086480165020201",         .oid_prefix="2.16.840.1.101.2.2.1"},
79         {.id=0x00000005, .bin_oid="0x6086480165020203",         .oid_prefix="2.16.840.1.101.2.2.3"},
80         {.id=0x00000006, .bin_oid="0x6086480165020105",         .oid_prefix="2.16.840.1.101.2.1.5"},
81         {.id=0x00000007, .bin_oid="0x6086480165020104",         .oid_prefix="2.16.840.1.101.2.1.4"},
82         {.id=0x00000008, .bin_oid="0x5505",                     .oid_prefix="2.5.5"},
83         {.id=0x00000009, .bin_oid="0x2A864886F7140104",         .oid_prefix="1.2.840.113556.1.4"},
84         {.id=0x0000000a, .bin_oid="0x2A864886F7140105",         .oid_prefix="1.2.840.113556.1.5"},
85         {.id=0x00000013, .bin_oid="0x0992268993F22C64",         .oid_prefix="0.9.2342.19200300.100"},
86         {.id=0x00000014, .bin_oid="0x6086480186F84203",         .oid_prefix="2.16.840.1.113730.3"},
87         {.id=0x00000015, .bin_oid="0x0992268993F22C6401",       .oid_prefix="0.9.2342.19200300.100.1"},
88         {.id=0x00000016, .bin_oid="0x6086480186F8420301",       .oid_prefix="2.16.840.1.113730.3.1"},
89         {.id=0x00000017, .bin_oid="0x2A864886F7140105B658",     .oid_prefix="1.2.840.113556.1.5.7000"},
90         {.id=0x00000018, .bin_oid="0x5515",                     .oid_prefix="2.5.21"},
91         {.id=0x00000019, .bin_oid="0x5512",                     .oid_prefix="2.5.18"},
92         {.id=0x0000001a, .bin_oid="0x5514",                     .oid_prefix="2.5.20"},
93         {.id=0x0000000b, .bin_oid="0x2A864886F71401048204",     .oid_prefix="1.2.840.113556.1.4.260"},
94         {.id=0x0000000c, .bin_oid="0x2A864886F714010538",       .oid_prefix="1.2.840.113556.1.5.56"},
95         {.id=0x0000000d, .bin_oid="0x2A864886F71401048206",     .oid_prefix="1.2.840.113556.1.4.262"},
96         {.id=0x0000000e, .bin_oid="0x2A864886F714010539",       .oid_prefix="1.2.840.113556.1.5.57"},
97         {.id=0x0000000f, .bin_oid="0x2A864886F71401048207",     .oid_prefix="1.2.840.113556.1.4.263"},
98         {.id=0x00000010, .bin_oid="0x2A864886F71401053A",       .oid_prefix="1.2.840.113556.1.5.58"},
99         {.id=0x00000011, .bin_oid="0x2A864886F714010549",       .oid_prefix="1.2.840.113556.1.5.73"},
100         {.id=0x00000012, .bin_oid="0x2A864886F71401048231",     .oid_prefix="1.2.840.113556.1.4.305"},
101         {.id=0x0000001b, .bin_oid="0x2B060104018B3A6577",       .oid_prefix="1.3.6.1.4.1.1466.101.119"},
102         {.id=0x0000001c, .bin_oid="0x6086480186F8420302",       .oid_prefix="2.16.840.1.113730.3.2"},
103         {.id=0x0000001d, .bin_oid="0x2B06010401817A01",         .oid_prefix="1.3.6.1.4.1.250.1"},
104         {.id=0x0000001e, .bin_oid="0x2A864886F70D0109",         .oid_prefix="1.2.840.113549.1.9"},
105         {.id=0x0000001f, .bin_oid="0x0992268993F22C6404",       .oid_prefix="0.9.2342.19200300.100.4"},
106         {.id=0x00000020, .bin_oid="0x2A864886F714010617",       .oid_prefix="1.2.840.113556.1.6.23"},
107         {.id=0x00000021, .bin_oid="0x2A864886F71401061201",     .oid_prefix="1.2.840.113556.1.6.18.1"},
108         {.id=0x00000022, .bin_oid="0x2A864886F71401061202",     .oid_prefix="1.2.840.113556.1.6.18.2"},
109         {.id=0x00000023, .bin_oid="0x2A864886F71401060D03",     .oid_prefix="1.2.840.113556.1.6.13.3"},
110         {.id=0x00000024, .bin_oid="0x2A864886F71401060D04",     .oid_prefix="1.2.840.113556.1.6.13.4"},
111         {.id=0x00000025, .bin_oid="0x2B0601010101",             .oid_prefix="1.3.6.1.1.1.1"},
112         {.id=0x00000026, .bin_oid="0x2B0601010102",             .oid_prefix="1.3.6.1.1.1.2"},
113         {.id=0x000003ed, .bin_oid="0x2A864886F7140104B65866",   .oid_prefix="1.2.840.113556.1.4.7000.102"},
114         {.id=0x00000428, .bin_oid="0x2A864886F7140105B6583E",   .oid_prefix="1.2.840.113556.1.5.7000.62"},
115         {.id=0x0000044c, .bin_oid="0x2A864886F7140104B6586683", .oid_prefix="1.2.840.113556.1.4.7000.102:0x83"},
116         {.id=0x0000044f, .bin_oid="0x2A864886F7140104B6586681", .oid_prefix="1.2.840.113556.1.4.7000.102:0x81"},
117         {.id=0x0000047d, .bin_oid="0x2A864886F7140105B6583E81", .oid_prefix="1.2.840.113556.1.5.7000.62:0x81"},
118         {.id=0x00000561, .bin_oid="0x2A864886F7140105B6583E83", .oid_prefix="1.2.840.113556.1.5.7000.62:0x83"},
119         {.id=0x000007d1, .bin_oid="0x2A864886F71401061401",     .oid_prefix="1.2.840.113556.1.6.20.1"},
120         {.id=0x000007e1, .bin_oid="0x2A864886F71401061402",     .oid_prefix="1.2.840.113556.1.6.20.2"},
121         {.id=0x00001b86, .bin_oid="0x2A817A",                   .oid_prefix="1.2.250"},
122         {.id=0x00001c78, .bin_oid="0x2A817A81",                 .oid_prefix="1.2.250:0x81"},
123         {.id=0x00001c7b, .bin_oid="0x2A817A8180",               .oid_prefix="1.2.250:0x8180"},
124 };
125
126
127 /**
128  * OID-to-ATTID mappings to be used for testing
129  */
130 static const struct {
131         const char      *oid;
132         uint32_t        id;
133         uint32_t        attid;
134 } _prefixmap_test_data[] = {
135         {.oid="2.5.4.0",                .id=0x00000000, .attid=0x000000},
136         {.oid="2.5.4.42",               .id=0x00000000, .attid=0x00002a},
137         {.oid="1.2.840.113556.1.2.1",   .id=0x00000002, .attid=0x020001},
138         {.oid="1.2.840.113556.1.2.13",  .id=0x00000002, .attid=0x02000d},
139         {.oid="1.2.840.113556.1.2.281", .id=0x00000002, .attid=0x020119},
140         {.oid="1.2.840.113556.1.4.125", .id=0x00000009, .attid=0x09007d},
141         {.oid="1.2.840.113556.1.4.146", .id=0x00000009, .attid=0x090092},
142         {.oid="1.2.250.1",              .id=0x00001b86, .attid=0x1b860001},
143         {.oid="1.2.250.130",            .id=0x00001b86, .attid=0x1b860082},
144         {.oid="1.2.250.16386",          .id=0x00001c78, .attid=0x1c788002},
145         {.oid="1.2.250.2097154",        .id=0x00001c7b, .attid=0x1c7b8002},
146 };
147
148
149 /**
150  * Creates dsdb_schema_prefixmap based on predefined data
151  *
152  */
153 static WERROR _drsut_prefixmap_new(const struct drsut_pfm_oid_data *_pfm_init_data, uint32_t count,
154                                    TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_pfm)
155 {
156         uint32_t i;
157         struct dsdb_schema_prefixmap *pfm;
158
159         pfm = talloc(mem_ctx, struct dsdb_schema_prefixmap);
160         W_ERROR_HAVE_NO_MEMORY(pfm);
161
162         pfm->length = count;
163         pfm->prefixes = talloc_array(pfm, struct dsdb_schema_prefixmap_oid, pfm->length);
164         if (!pfm->prefixes) {
165                 talloc_free(pfm);
166                 return WERR_NOMEM;
167         }
168
169         for (i = 0; i < pfm->length; i++) {
170                 pfm->prefixes[i].id = _pfm_init_data[i].id;
171                 pfm->prefixes[i].bin_oid = strhex_to_data_blob(pfm, _pfm_init_data[i].bin_oid);
172                 if (!pfm->prefixes[i].bin_oid.data) {
173                         talloc_free(pfm);
174                         return WERR_NOMEM;
175                 }
176         }
177
178         *_pfm = pfm;
179
180         return WERR_OK;
181 }
182
183 static bool _torture_drs_pfm_compare_same(struct torture_context *tctx,
184                                           const struct dsdb_schema_prefixmap *pfm_left,
185                                           const struct dsdb_schema_prefixmap *pfm_right)
186 {
187         uint32_t i;
188
189         torture_assert_int_equal(tctx, pfm_left->length, pfm_right->length,
190                                  "prefixMaps differ in size");
191         for (i = 0; i < pfm_left->length; i++) {
192                 struct dsdb_schema_prefixmap_oid *entry_left = &pfm_left->prefixes[i];
193                 struct dsdb_schema_prefixmap_oid *entry_right = &pfm_right->prefixes[i];
194
195                 torture_assert(tctx, entry_left->id == entry_right->id,
196                                 talloc_asprintf(tctx, "Different IDs for index=%d", i));
197                 torture_assert_data_blob_equal(tctx, entry_left->bin_oid, entry_right->bin_oid,
198                                                 talloc_asprintf(tctx, "Different bin_oid for index=%d", i));
199         }
200
201         return true;
202 }
203
204 /*
205  * Tests dsdb_schema_pfm_new()
206  */
207 static bool torture_drs_unit_pfm_new(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
208 {
209         WERROR werr;
210         bool bret;
211         TALLOC_CTX *mem_ctx;
212         struct dsdb_schema_prefixmap *pfm = NULL;
213
214         mem_ctx = talloc_new(priv);
215
216         /* create new prefix map */
217         werr = dsdb_schema_pfm_new(mem_ctx, &pfm);
218         torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_new() failed!");
219         torture_assert(tctx, pfm != NULL, "NULL prefixMap created!");
220         torture_assert(tctx, pfm->length > 0, "Empty prefixMap created!");
221         torture_assert(tctx, pfm->prefixes != NULL, "No prefixes for newly created prefixMap!");
222
223         /* compare newly created prefixMap with template one */
224         bret = _torture_drs_pfm_compare_same(tctx, priv->pfm_new, pfm);
225
226         talloc_free(mem_ctx);
227
228         return bret;
229 }
230
231 /**
232  * Tests dsdb_schema_pfm_make_attid() using full prefixMap.
233  * In this test we know exactly which ATTID and prefixMap->ID
234  * should be returned, i.e. no prefixMap entries should be added.
235  */
236 static bool torture_drs_unit_pfm_make_attid_full_map(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
237 {
238         WERROR werr;
239         uint32_t i, count;
240         uint32_t attid;
241         char *err_msg;
242
243         count = ARRAY_SIZE(_prefixmap_test_data);
244         for (i = 0; i < count; i++) {
245                 werr = dsdb_schema_pfm_make_attid(priv->pfm_full, _prefixmap_test_data[i].oid, &attid);
246                 /* prepare error message */
247                 err_msg = talloc_asprintf(priv, "dsdb_schema_pfm_make_attid() failed with %s",
248                                                 _prefixmap_test_data[i].oid);
249                 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
250                 /* verify result and returned ATTID */
251                 torture_assert_werr_ok(tctx, werr, err_msg);
252                 torture_assert_int_equal(tctx, attid, _prefixmap_test_data[i].attid, err_msg);
253                 /* reclaim memory for prepared error message */
254                 talloc_free(err_msg);
255         }
256
257         return true;
258 }
259
260 /**
261  * Tests dsdb_schema_pfm_make_attid() using initially small prefixMap.
262  * In this test we don't know exactly which ATTID and prefixMap->ID
263  * should be returned, but we can verify lo-word of ATTID.
264  * This test verifies implementation branch when a new
265  * prefix should be added into prefixMap.
266  */
267 static bool torture_drs_unit_pfm_make_attid_small_map(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
268 {
269         WERROR werr;
270         uint32_t i, j;
271         uint32_t idx;
272         uint32_t attid, attid_2;
273         char *err_msg;
274         struct dsdb_schema_prefixmap *pfm = NULL;
275         TALLOC_CTX *mem_ctx;
276
277         mem_ctx = talloc_new(priv);
278
279         /* create new prefix map */
280         werr = dsdb_schema_pfm_new(mem_ctx, &pfm);
281         torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_new() failed!");
282         torture_assert(tctx, pfm != NULL, "NULL prefixMap created!");
283         torture_assert(tctx, pfm->length > 0, "Empty prefixMap created!");
284         torture_assert(tctx, pfm->prefixes != NULL, "No prefixes for newly created prefixMap!");
285
286         /* make some ATTIDs and check result */
287         for (i = 0; i < ARRAY_SIZE(_prefixmap_test_data); i++) {
288                 werr = dsdb_schema_pfm_make_attid(pfm, _prefixmap_test_data[i].oid, &attid);
289
290                 /* prepare error message */
291                 err_msg = talloc_asprintf(mem_ctx, "dsdb_schema_pfm_make_attid() failed with %s",
292                                                 _prefixmap_test_data[i].oid);
293                 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
294
295                 /* verify result and returned ATTID */
296                 torture_assert_werr_ok(tctx, werr, err_msg);
297                 /* verify ATTID lo-word */
298                 torture_assert_int_equal(tctx, attid & 0xFFFF, _prefixmap_test_data[i].attid & 0xFFFF, err_msg);
299
300                 /* try again, this time verify for whole ATTID */
301                 werr = dsdb_schema_pfm_make_attid(pfm, _prefixmap_test_data[i].oid, &attid_2);
302                 torture_assert_werr_ok(tctx, werr, err_msg);
303                 torture_assert_int_equal(tctx, attid_2, attid, err_msg);
304
305                 /* reclaim memory for prepared error message */
306                 talloc_free(err_msg);
307
308                 /* check there is such an index in modified prefixMap */
309                 idx = (attid >> 16);
310                 for (j = 0; j < pfm->length; j++) {
311                         if (pfm->prefixes[j].id == idx)
312                                 break;
313                 }
314                 if (j >= pfm->length) {
315                         torture_result(tctx, TORTURE_FAIL, __location__": No prefix for ATTID=0x%08X", attid);
316                         return false;
317                 }
318
319         }
320
321         talloc_free(mem_ctx);
322
323         return true;
324 }
325
326 /**
327  * Tests dsdb_schema_pfm_oid_from_attid() using full prefixMap.
328  */
329 static bool torture_drs_unit_pfm_oid_from_attid(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
330 {
331         WERROR werr;
332         uint32_t i, count;
333         char *err_msg;
334         const char *oid;
335
336         count = ARRAY_SIZE(_prefixmap_test_data);
337         for (i = 0; i < count; i++) {
338                 oid = NULL;
339                 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, _prefixmap_test_data[i].attid,
340                                                       priv, &oid);
341                 /* prepare error message */
342                 err_msg = talloc_asprintf(priv, "dsdb_schema_pfm_oid_from_attid() failed with 0x%08X",
343                                                 _prefixmap_test_data[i].attid);
344                 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
345                 /* verify result and returned ATTID */
346                 torture_assert_werr_ok(tctx, werr, err_msg);
347                 torture_assert(tctx, oid, "dsdb_schema_pfm_oid_from_attid() returned NULL OID!!!");
348                 torture_assert_str_equal(tctx, oid, _prefixmap_test_data[i].oid, err_msg);
349                 /* reclaim memory for prepared error message */
350                 talloc_free(err_msg);
351                 /* free memory for OID */
352                 talloc_free(discard_const(oid));
353         }
354
355         return true;
356 }
357
358
359 /*
360  * Setup/Teardown for test case
361  */
362 static bool torture_drs_unit_prefixmap_setup(struct torture_context *tctx, struct drsut_prefixmap_data **priv)
363 {
364         WERROR werr;
365
366         *priv = talloc_zero(tctx, struct drsut_prefixmap_data);
367         torture_assert(tctx, *priv != NULL, "Not enough memory");
368
369         werr = _drsut_prefixmap_new(_prefixmap_test_new_data, ARRAY_SIZE(_prefixmap_test_new_data), tctx, &(*priv)->pfm_new);
370         torture_assert_werr_ok(tctx, werr, "failed to create pfm_new");
371
372         werr = _drsut_prefixmap_new(_prefixmap_full_map_data, ARRAY_SIZE(_prefixmap_full_map_data), tctx, &(*priv)->pfm_full);
373         torture_assert_werr_ok(tctx, werr, "failed to create pfm_test");
374
375         return true;
376 }
377
378 static bool torture_drs_unit_prefixmap_teardown(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
379 {
380         talloc_free(priv);
381
382         return true;
383 }
384
385 /**
386  * Test case initialization for
387  * DRS-UNIT.prefixMap
388  */
389 struct torture_tcase * torture_drs_unit_prefixmap(struct torture_suite *suite)
390 {
391         typedef bool (*pfn_setup)(struct torture_context *, void **);
392         typedef bool (*pfn_teardown)(struct torture_context *, void *);
393         typedef bool (*pfn_run)(struct torture_context *, void *);
394
395         struct torture_tcase * tc = torture_suite_add_tcase(suite, "prefixMap");
396
397         torture_tcase_set_fixture(tc,
398                                   (pfn_setup)torture_drs_unit_prefixmap_setup,
399                                   (pfn_teardown)torture_drs_unit_prefixmap_teardown);
400
401         tc->description = talloc_strdup(tc, "Unit tests for DRSUAPI::prefixMap implementation");
402
403         torture_tcase_add_simple_test(tc, "new", (pfn_run)torture_drs_unit_pfm_new);
404
405         torture_tcase_add_simple_test(tc, "make_attid_full_map", (pfn_run)torture_drs_unit_pfm_make_attid_full_map);
406         torture_tcase_add_simple_test(tc, "make_attid_small_map", (pfn_run)torture_drs_unit_pfm_make_attid_small_map);
407         torture_tcase_add_simple_test(tc, "oid_from_attid_full_map", (pfn_run)torture_drs_unit_pfm_oid_from_attid);
408
409         return tc;
410 }