s4/drs(tort): Create temporary LDB for testing purposes
[ira/wip.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 "system/filesys.h"
24 #include "torture/smbtorture.h"
25 #include "dsdb/samdb/samdb.h"
26 #include "torture/rpc/drsuapi.h"
27 #include "param/param.h"
28
29
30 /**
31  * Private data to be shared among all test in Test case
32  */
33 struct drsut_prefixmap_data {
34         struct dsdb_schema_prefixmap *pfm_new;
35         struct dsdb_schema_prefixmap *pfm_full;
36
37         struct ldb_context *ldb_ctx;
38 };
39
40 /**
41  * Test-oid data structure
42  */
43 struct drsut_pfm_oid_data {
44         uint32_t        id;
45         const char      *bin_oid;
46         const char      *oid_prefix;
47 };
48
49 /**
50  * Default prefixMap initialization data
51  */
52 static const struct drsut_pfm_oid_data _prefixmap_test_new_data[] = {
53         {.id=0x00000000, .bin_oid="5504",                 .oid_prefix="2.5.4"},
54         {.id=0x00000001, .bin_oid="5506",                 .oid_prefix="2.5.6"},
55         {.id=0x00000002, .bin_oid="2A864886F7140102",     .oid_prefix="1.2.840.113556.1.2"},
56         {.id=0x00000003, .bin_oid="2A864886F7140103",     .oid_prefix="1.2.840.113556.1.3"},
57         {.id=0x00000004, .bin_oid="6086480165020201",     .oid_prefix="2.16.840.1.101.2.2.1"},
58         {.id=0x00000005, .bin_oid="6086480165020203",     .oid_prefix="2.16.840.1.101.2.2.3"},
59         {.id=0x00000006, .bin_oid="6086480165020105",     .oid_prefix="2.16.840.1.101.2.1.5"},
60         {.id=0x00000007, .bin_oid="6086480165020104",     .oid_prefix="2.16.840.1.101.2.1.4"},
61         {.id=0x00000008, .bin_oid="5505",                 .oid_prefix="2.5.5"},
62         {.id=0x00000009, .bin_oid="2A864886F7140104",     .oid_prefix="1.2.840.113556.1.4"},
63         {.id=0x0000000A, .bin_oid="2A864886F7140105",     .oid_prefix="1.2.840.113556.1.5"},
64         {.id=0x00000013, .bin_oid="0992268993F22C64",     .oid_prefix="0.9.2342.19200300.100"},
65         {.id=0x00000014, .bin_oid="6086480186F84203",     .oid_prefix="2.16.840.1.113730.3"},
66         {.id=0x00000015, .bin_oid="0992268993F22C6401",   .oid_prefix="0.9.2342.19200300.100.1"},
67         {.id=0x00000016, .bin_oid="6086480186F8420301",   .oid_prefix="2.16.840.1.113730.3.1"},
68         {.id=0x00000017, .bin_oid="2A864886F7140105B658", .oid_prefix="1.2.840.113556.1.5.7000"},
69         {.id=0x00000018, .bin_oid="5515",                 .oid_prefix="2.5.21"},
70         {.id=0x00000019, .bin_oid="5512",                 .oid_prefix="2.5.18"},
71         {.id=0x0000001A, .bin_oid="5514",                 .oid_prefix="2.5.20"},
72 };
73
74 /**
75  * Data to be used for creating full prefix map for testing
76  */
77 static const struct drsut_pfm_oid_data _prefixmap_full_map_data[] = {
78         {.id=0x00000000, .bin_oid="0x5504",                     .oid_prefix="2.5.4"},
79         {.id=0x00000001, .bin_oid="0x5506",                     .oid_prefix="2.5.6"},
80         {.id=0x00000002, .bin_oid="0x2A864886F7140102",         .oid_prefix="1.2.840.113556.1.2"},
81         {.id=0x00000003, .bin_oid="0x2A864886F7140103",         .oid_prefix="1.2.840.113556.1.3"},
82         {.id=0x00000004, .bin_oid="0x6086480165020201",         .oid_prefix="2.16.840.1.101.2.2.1"},
83         {.id=0x00000005, .bin_oid="0x6086480165020203",         .oid_prefix="2.16.840.1.101.2.2.3"},
84         {.id=0x00000006, .bin_oid="0x6086480165020105",         .oid_prefix="2.16.840.1.101.2.1.5"},
85         {.id=0x00000007, .bin_oid="0x6086480165020104",         .oid_prefix="2.16.840.1.101.2.1.4"},
86         {.id=0x00000008, .bin_oid="0x5505",                     .oid_prefix="2.5.5"},
87         {.id=0x00000009, .bin_oid="0x2A864886F7140104",         .oid_prefix="1.2.840.113556.1.4"},
88         {.id=0x0000000a, .bin_oid="0x2A864886F7140105",         .oid_prefix="1.2.840.113556.1.5"},
89         {.id=0x00000013, .bin_oid="0x0992268993F22C64",         .oid_prefix="0.9.2342.19200300.100"},
90         {.id=0x00000014, .bin_oid="0x6086480186F84203",         .oid_prefix="2.16.840.1.113730.3"},
91         {.id=0x00000015, .bin_oid="0x0992268993F22C6401",       .oid_prefix="0.9.2342.19200300.100.1"},
92         {.id=0x00000016, .bin_oid="0x6086480186F8420301",       .oid_prefix="2.16.840.1.113730.3.1"},
93         {.id=0x00000017, .bin_oid="0x2A864886F7140105B658",     .oid_prefix="1.2.840.113556.1.5.7000"},
94         {.id=0x00000018, .bin_oid="0x5515",                     .oid_prefix="2.5.21"},
95         {.id=0x00000019, .bin_oid="0x5512",                     .oid_prefix="2.5.18"},
96         {.id=0x0000001a, .bin_oid="0x5514",                     .oid_prefix="2.5.20"},
97         {.id=0x0000000b, .bin_oid="0x2A864886F71401048204",     .oid_prefix="1.2.840.113556.1.4.260"},
98         {.id=0x0000000c, .bin_oid="0x2A864886F714010538",       .oid_prefix="1.2.840.113556.1.5.56"},
99         {.id=0x0000000d, .bin_oid="0x2A864886F71401048206",     .oid_prefix="1.2.840.113556.1.4.262"},
100         {.id=0x0000000e, .bin_oid="0x2A864886F714010539",       .oid_prefix="1.2.840.113556.1.5.57"},
101         {.id=0x0000000f, .bin_oid="0x2A864886F71401048207",     .oid_prefix="1.2.840.113556.1.4.263"},
102         {.id=0x00000010, .bin_oid="0x2A864886F71401053A",       .oid_prefix="1.2.840.113556.1.5.58"},
103         {.id=0x00000011, .bin_oid="0x2A864886F714010549",       .oid_prefix="1.2.840.113556.1.5.73"},
104         {.id=0x00000012, .bin_oid="0x2A864886F71401048231",     .oid_prefix="1.2.840.113556.1.4.305"},
105         {.id=0x0000001b, .bin_oid="0x2B060104018B3A6577",       .oid_prefix="1.3.6.1.4.1.1466.101.119"},
106         {.id=0x0000001c, .bin_oid="0x6086480186F8420302",       .oid_prefix="2.16.840.1.113730.3.2"},
107         {.id=0x0000001d, .bin_oid="0x2B06010401817A01",         .oid_prefix="1.3.6.1.4.1.250.1"},
108         {.id=0x0000001e, .bin_oid="0x2A864886F70D0109",         .oid_prefix="1.2.840.113549.1.9"},
109         {.id=0x0000001f, .bin_oid="0x0992268993F22C6404",       .oid_prefix="0.9.2342.19200300.100.4"},
110         {.id=0x00000020, .bin_oid="0x2A864886F714010617",       .oid_prefix="1.2.840.113556.1.6.23"},
111         {.id=0x00000021, .bin_oid="0x2A864886F71401061201",     .oid_prefix="1.2.840.113556.1.6.18.1"},
112         {.id=0x00000022, .bin_oid="0x2A864886F71401061202",     .oid_prefix="1.2.840.113556.1.6.18.2"},
113         {.id=0x00000023, .bin_oid="0x2A864886F71401060D03",     .oid_prefix="1.2.840.113556.1.6.13.3"},
114         {.id=0x00000024, .bin_oid="0x2A864886F71401060D04",     .oid_prefix="1.2.840.113556.1.6.13.4"},
115         {.id=0x00000025, .bin_oid="0x2B0601010101",             .oid_prefix="1.3.6.1.1.1.1"},
116         {.id=0x00000026, .bin_oid="0x2B0601010102",             .oid_prefix="1.3.6.1.1.1.2"},
117         {.id=0x000003ed, .bin_oid="0x2A864886F7140104B65866",   .oid_prefix="1.2.840.113556.1.4.7000.102"},
118         {.id=0x00000428, .bin_oid="0x2A864886F7140105B6583E",   .oid_prefix="1.2.840.113556.1.5.7000.62"},
119         {.id=0x0000044c, .bin_oid="0x2A864886F7140104B6586683", .oid_prefix="1.2.840.113556.1.4.7000.102:0x83"},
120         {.id=0x0000044f, .bin_oid="0x2A864886F7140104B6586681", .oid_prefix="1.2.840.113556.1.4.7000.102:0x81"},
121         {.id=0x0000047d, .bin_oid="0x2A864886F7140105B6583E81", .oid_prefix="1.2.840.113556.1.5.7000.62:0x81"},
122         {.id=0x00000561, .bin_oid="0x2A864886F7140105B6583E83", .oid_prefix="1.2.840.113556.1.5.7000.62:0x83"},
123         {.id=0x000007d1, .bin_oid="0x2A864886F71401061401",     .oid_prefix="1.2.840.113556.1.6.20.1"},
124         {.id=0x000007e1, .bin_oid="0x2A864886F71401061402",     .oid_prefix="1.2.840.113556.1.6.20.2"},
125         {.id=0x00001b86, .bin_oid="0x2A817A",                   .oid_prefix="1.2.250"},
126         {.id=0x00001c78, .bin_oid="0x2A817A81",                 .oid_prefix="1.2.250:0x81"},
127         {.id=0x00001c7b, .bin_oid="0x2A817A8180",               .oid_prefix="1.2.250:0x8180"},
128 };
129
130
131 /**
132  * OID-to-ATTID mappings to be used for testing
133  */
134 static const struct {
135         const char      *oid;
136         uint32_t        id;
137         uint32_t        attid;
138 } _prefixmap_test_data[] = {
139         {.oid="2.5.4.0",                .id=0x00000000, .attid=0x000000},
140         {.oid="2.5.4.42",               .id=0x00000000, .attid=0x00002a},
141         {.oid="1.2.840.113556.1.2.1",   .id=0x00000002, .attid=0x020001},
142         {.oid="1.2.840.113556.1.2.13",  .id=0x00000002, .attid=0x02000d},
143         {.oid="1.2.840.113556.1.2.281", .id=0x00000002, .attid=0x020119},
144         {.oid="1.2.840.113556.1.4.125", .id=0x00000009, .attid=0x09007d},
145         {.oid="1.2.840.113556.1.4.146", .id=0x00000009, .attid=0x090092},
146         {.oid="1.2.250.1",              .id=0x00001b86, .attid=0x1b860001},
147         {.oid="1.2.250.130",            .id=0x00001b86, .attid=0x1b860082},
148         {.oid="1.2.250.16386",          .id=0x00001c78, .attid=0x1c788002},
149         {.oid="1.2.250.2097154",        .id=0x00001c7b, .attid=0x1c7b8002},
150 };
151
152
153 /**
154  * Creates dsdb_schema_prefixmap based on predefined data
155  *
156  */
157 static WERROR _drsut_prefixmap_new(const struct drsut_pfm_oid_data *_pfm_init_data, uint32_t count,
158                                    TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_pfm)
159 {
160         uint32_t i;
161         struct dsdb_schema_prefixmap *pfm;
162
163         pfm = talloc(mem_ctx, struct dsdb_schema_prefixmap);
164         W_ERROR_HAVE_NO_MEMORY(pfm);
165
166         pfm->length = count;
167         pfm->prefixes = talloc_array(pfm, struct dsdb_schema_prefixmap_oid, pfm->length);
168         if (!pfm->prefixes) {
169                 talloc_free(pfm);
170                 return WERR_NOMEM;
171         }
172
173         for (i = 0; i < pfm->length; i++) {
174                 pfm->prefixes[i].id = _pfm_init_data[i].id;
175                 pfm->prefixes[i].bin_oid = strhex_to_data_blob(pfm, _pfm_init_data[i].bin_oid);
176                 if (!pfm->prefixes[i].bin_oid.data) {
177                         talloc_free(pfm);
178                         return WERR_NOMEM;
179                 }
180         }
181
182         *_pfm = pfm;
183
184         return WERR_OK;
185 }
186
187 static bool _torture_drs_pfm_compare_same(struct torture_context *tctx,
188                                           const struct dsdb_schema_prefixmap *pfm_left,
189                                           const struct dsdb_schema_prefixmap *pfm_right)
190 {
191         uint32_t i;
192
193         torture_assert_int_equal(tctx, pfm_left->length, pfm_right->length,
194                                  "prefixMaps differ in size");
195         for (i = 0; i < pfm_left->length; i++) {
196                 struct dsdb_schema_prefixmap_oid *entry_left = &pfm_left->prefixes[i];
197                 struct dsdb_schema_prefixmap_oid *entry_right = &pfm_right->prefixes[i];
198
199                 torture_assert(tctx, entry_left->id == entry_right->id,
200                                 talloc_asprintf(tctx, "Different IDs for index=%d", i));
201                 torture_assert_data_blob_equal(tctx, entry_left->bin_oid, entry_right->bin_oid,
202                                                 talloc_asprintf(tctx, "Different bin_oid for index=%d", i));
203         }
204
205         return true;
206 }
207
208 /*
209  * Tests dsdb_schema_pfm_new()
210  */
211 static bool torture_drs_unit_pfm_new(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
212 {
213         WERROR werr;
214         bool bret;
215         TALLOC_CTX *mem_ctx;
216         struct dsdb_schema_prefixmap *pfm = NULL;
217
218         mem_ctx = talloc_new(priv);
219
220         /* create new prefix map */
221         werr = dsdb_schema_pfm_new(mem_ctx, &pfm);
222         torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_new() failed!");
223         torture_assert(tctx, pfm != NULL, "NULL prefixMap created!");
224         torture_assert(tctx, pfm->length > 0, "Empty prefixMap created!");
225         torture_assert(tctx, pfm->prefixes != NULL, "No prefixes for newly created prefixMap!");
226
227         /* compare newly created prefixMap with template one */
228         bret = _torture_drs_pfm_compare_same(tctx, priv->pfm_new, pfm);
229
230         talloc_free(mem_ctx);
231
232         return bret;
233 }
234
235 /**
236  * Tests dsdb_schema_pfm_make_attid() using full prefixMap.
237  * In this test we know exactly which ATTID and prefixMap->ID
238  * should be returned, i.e. no prefixMap entries should be added.
239  */
240 static bool torture_drs_unit_pfm_make_attid_full_map(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
241 {
242         WERROR werr;
243         uint32_t i, count;
244         uint32_t attid;
245         char *err_msg;
246
247         count = ARRAY_SIZE(_prefixmap_test_data);
248         for (i = 0; i < count; i++) {
249                 werr = dsdb_schema_pfm_make_attid(priv->pfm_full, _prefixmap_test_data[i].oid, &attid);
250                 /* prepare error message */
251                 err_msg = talloc_asprintf(priv, "dsdb_schema_pfm_make_attid() failed with %s",
252                                                 _prefixmap_test_data[i].oid);
253                 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
254                 /* verify result and returned ATTID */
255                 torture_assert_werr_ok(tctx, werr, err_msg);
256                 torture_assert_int_equal(tctx, attid, _prefixmap_test_data[i].attid, err_msg);
257                 /* reclaim memory for prepared error message */
258                 talloc_free(err_msg);
259         }
260
261         return true;
262 }
263
264 /**
265  * Tests dsdb_schema_pfm_make_attid() using initially small prefixMap.
266  * In this test we don't know exactly which ATTID and prefixMap->ID
267  * should be returned, but we can verify lo-word of ATTID.
268  * This test verifies implementation branch when a new
269  * prefix should be added into prefixMap.
270  */
271 static bool torture_drs_unit_pfm_make_attid_small_map(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
272 {
273         WERROR werr;
274         uint32_t i, j;
275         uint32_t idx;
276         uint32_t attid, attid_2;
277         char *err_msg;
278         struct dsdb_schema_prefixmap *pfm = NULL;
279         TALLOC_CTX *mem_ctx;
280
281         mem_ctx = talloc_new(priv);
282
283         /* create new prefix map */
284         werr = dsdb_schema_pfm_new(mem_ctx, &pfm);
285         torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_new() failed!");
286         torture_assert(tctx, pfm != NULL, "NULL prefixMap created!");
287         torture_assert(tctx, pfm->length > 0, "Empty prefixMap created!");
288         torture_assert(tctx, pfm->prefixes != NULL, "No prefixes for newly created prefixMap!");
289
290         /* make some ATTIDs and check result */
291         for (i = 0; i < ARRAY_SIZE(_prefixmap_test_data); i++) {
292                 werr = dsdb_schema_pfm_make_attid(pfm, _prefixmap_test_data[i].oid, &attid);
293
294                 /* prepare error message */
295                 err_msg = talloc_asprintf(mem_ctx, "dsdb_schema_pfm_make_attid() failed with %s",
296                                                 _prefixmap_test_data[i].oid);
297                 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
298
299                 /* verify result and returned ATTID */
300                 torture_assert_werr_ok(tctx, werr, err_msg);
301                 /* verify ATTID lo-word */
302                 torture_assert_int_equal(tctx, attid & 0xFFFF, _prefixmap_test_data[i].attid & 0xFFFF, err_msg);
303
304                 /* try again, this time verify for whole ATTID */
305                 werr = dsdb_schema_pfm_make_attid(pfm, _prefixmap_test_data[i].oid, &attid_2);
306                 torture_assert_werr_ok(tctx, werr, err_msg);
307                 torture_assert_int_equal(tctx, attid_2, attid, err_msg);
308
309                 /* reclaim memory for prepared error message */
310                 talloc_free(err_msg);
311
312                 /* check there is such an index in modified prefixMap */
313                 idx = (attid >> 16);
314                 for (j = 0; j < pfm->length; j++) {
315                         if (pfm->prefixes[j].id == idx)
316                                 break;
317                 }
318                 if (j >= pfm->length) {
319                         torture_result(tctx, TORTURE_FAIL, __location__": No prefix for ATTID=0x%08X", attid);
320                         return false;
321                 }
322
323         }
324
325         talloc_free(mem_ctx);
326
327         return true;
328 }
329
330 /**
331  * Tests dsdb_schema_pfm_oid_from_attid() using full prefixMap.
332  */
333 static bool torture_drs_unit_pfm_oid_from_attid(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
334 {
335         WERROR werr;
336         uint32_t i, count;
337         char *err_msg;
338         const char *oid;
339
340         count = ARRAY_SIZE(_prefixmap_test_data);
341         for (i = 0; i < count; i++) {
342                 oid = NULL;
343                 werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, _prefixmap_test_data[i].attid,
344                                                       priv, &oid);
345                 /* prepare error message */
346                 err_msg = talloc_asprintf(priv, "dsdb_schema_pfm_oid_from_attid() failed with 0x%08X",
347                                                 _prefixmap_test_data[i].attid);
348                 torture_assert(tctx, err_msg, "Unexpected: Have no memory!");
349                 /* verify result and returned ATTID */
350                 torture_assert_werr_ok(tctx, werr, err_msg);
351                 torture_assert(tctx, oid, "dsdb_schema_pfm_oid_from_attid() returned NULL OID!!!");
352                 torture_assert_str_equal(tctx, oid, _prefixmap_test_data[i].oid, err_msg);
353                 /* reclaim memory for prepared error message */
354                 talloc_free(err_msg);
355                 /* free memory for OID */
356                 talloc_free(discard_const(oid));
357         }
358
359         return true;
360 }
361
362 /**
363  * Test Schema prefixMap conversions to/from drsuapi prefixMap
364  * representation.
365  */
366 static bool torture_drs_unit_pfm_to_from_drsuapi(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
367 {
368         WERROR werr;
369         const char *schema_info;
370         const char *schema_info_default = "FF0000000000000000000000000000000123456789";
371         struct dsdb_schema_prefixmap *pfm;
372         struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
373         TALLOC_CTX *mem_ctx;
374
375         mem_ctx = talloc_new(tctx);
376         torture_assert(tctx, mem_ctx, "Unexpected: Have no memory!");
377
378         /* convert Schema_prefixMap to drsuapi_prefixMap */
379         werr = dsdb_drsuapi_pfm_from_schema_pfm(priv->pfm_full, schema_info_default, mem_ctx, &ctr);
380         torture_assert_werr_ok(tctx, werr, "dsdb_drsuapi_pfm_from_schema_pfm() failed");
381         torture_assert(tctx, ctr && ctr->mappings, "drsuapi_prefixMap not constructed correctly");
382         torture_assert_int_equal(tctx, ctr->num_mappings, priv->pfm_full->length + 1,
383                                  "drs_mappings count does not match");
384         /* look for schema_info entry - it should be the last one */
385         schema_info = hex_encode_talloc(mem_ctx,
386                                         ctr->mappings[ctr->num_mappings - 1].oid.binary_oid,
387                                         ctr->mappings[ctr->num_mappings - 1].oid.length);
388         torture_assert_str_equal(tctx,
389                                  schema_info,
390                                  schema_info_default,
391                                  "schema_info not stored correctly or not last entry");
392
393         /* compare schema_prefixMap and drsuapi_prefixMap */
394         werr = dsdb_schema_pfm_contains_drsuapi_pfm(priv->pfm_full, ctr);
395         torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_contains_drsuapi_pfm() failed");
396
397         /* convert back drsuapi_prefixMap to schema_prefixMap */
398         werr = dsdb_schema_pfm_from_drsuapi_pfm(ctr, true, mem_ctx, &pfm, &schema_info);
399         torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_from_drsuapi_pfm() failed");
400         torture_assert_str_equal(tctx, schema_info, schema_info_default, "Fetched schema_info is different");
401         /* compare against the original */
402         if (!_torture_drs_pfm_compare_same(tctx, priv->pfm_full, pfm)) {
403                 talloc_free(mem_ctx);
404                 return false;
405         }
406
407         /* test conversion with partial drsuapi_prefixMap */
408         ctr->num_mappings--;
409         werr = dsdb_schema_pfm_from_drsuapi_pfm(ctr, false, mem_ctx, &pfm, NULL);
410         torture_assert_werr_ok(tctx, werr, "dsdb_schema_pfm_from_drsuapi_pfm() failed");
411         /* compare against the original */
412         if (!_torture_drs_pfm_compare_same(tctx, priv->pfm_full, pfm)) {
413                 talloc_free(mem_ctx);
414                 return false;
415         }
416
417         talloc_free(mem_ctx);
418         return true;
419 }
420
421
422 /**
423  * Test Schema prefixMap conversions to/from ldb_val
424  * blob representation.
425  */
426 static bool torture_drs_unit_pfm_to_from_ldb_val(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
427 {
428         WERROR werr;
429         const char *schema_info;
430         const char *schema_info_default = "FF0000000000000000000000000000000123456789";
431         struct dsdb_schema *schema;
432         struct ldb_val pfm_ldb_val;
433         struct ldb_val schema_info_ldb_val;
434         TALLOC_CTX *mem_ctx;
435
436         mem_ctx = talloc_new(tctx);
437         torture_assert(tctx, mem_ctx, "Unexpected: Have no memory!");
438
439         schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(tctx->lp_ctx));
440         torture_assert(tctx, schema, "Unexpected: failed to allocate schema object");
441
442         /* set priv->pfm_full as prefixMap for new schema object */
443         schema->prefixmap = priv->pfm_full;
444         schema->schema_info = schema_info_default;
445
446         /* convert schema_prefixMap to ldb_val blob */
447         werr = dsdb_get_oid_mappings_ldb(schema, mem_ctx, &pfm_ldb_val, &schema_info_ldb_val);
448         torture_assert_werr_ok(tctx, werr, "dsdb_get_oid_mappings_ldb() failed");
449         torture_assert(tctx, pfm_ldb_val.data && pfm_ldb_val.length,
450                        "pfm_ldb_val not constructed correctly");
451         torture_assert(tctx, schema_info_ldb_val.data && schema_info_ldb_val.length,
452                        "schema_info_ldb_val not constructed correctly");
453         /* look for schema_info entry - it should be the last one */
454         schema_info = hex_encode_talloc(mem_ctx,
455                                         schema_info_ldb_val.data,
456                                         schema_info_ldb_val.length);
457         torture_assert_str_equal(tctx,
458                                  schema_info,
459                                  schema_info_default,
460                                  "schema_info not stored correctly or not last entry");
461
462         /* convert pfm_ldb_val back to schema_prefixMap */
463         schema->prefixmap = NULL;
464         schema->schema_info = NULL;
465         werr = dsdb_load_oid_mappings_ldb(schema, &pfm_ldb_val, &schema_info_ldb_val);
466         torture_assert_werr_ok(tctx, werr, "dsdb_load_oid_mappings_ldb() failed");
467         /* compare against the original */
468         if (!_torture_drs_pfm_compare_same(tctx, schema->prefixmap, priv->pfm_full)) {
469                 talloc_free(mem_ctx);
470                 return false;
471         }
472
473         talloc_free(mem_ctx);
474         return true;
475 }
476
477
478 /**
479  * Prepare temporary LDB and opens it
480  */
481 static bool torture_drs_unit_ldb_setup(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
482 {
483         int fd = -1;
484         int ldb_err;
485         char *ldb_url;
486         bool bret = true;
487         TALLOC_CTX* mem_ctx;
488
489         mem_ctx = talloc_new(priv);
490
491         /* try to find to make temporary LDB_ULR */
492         ldb_url = getenv("LDB_URL");
493         if (!ldb_url) {
494                 const char *temp_dir;
495                 temp_dir = getenv("TEST_DATA_PREFIX");
496                 if (!temp_dir) {
497                         temp_dir = "/tmp";
498                 }
499                 ldb_url = talloc_asprintf(priv, "%s/drs_XXXXXX", temp_dir);
500                 fd = mkstemp(ldb_url);
501                 torture_assert(tctx, fd != -1,
502                                talloc_asprintf(mem_ctx, "mkstemp() failed: %s", strerror(errno)));
503         }
504
505         /* create LDB */
506         priv->ldb_ctx = ldb_init(priv, tctx->ev);
507         ldb_err = ldb_connect(priv->ldb_ctx, ldb_url, 0, NULL);
508         torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE, "ldb_connect() failed");
509
510         /* set some schemaNamingContext */
511         ldb_err = ldb_set_opaque(priv->ldb_ctx,
512                                  "schemaNamingContext",
513                                  ldb_dn_new(priv->ldb_ctx, priv->ldb_ctx, "CN=Schema,CN=Config"));
514         torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE, "ldb_set_opaque() failed");
515
516         /* add prefixMap attribute so tested layer could work properly */
517         {
518                 struct ldb_message *msg = ldb_msg_new(mem_ctx);
519                 msg->dn = samdb_schema_dn(priv->ldb_ctx);
520                 ldb_err = ldb_msg_add_string(msg, "prefixMap", "prefixMap");
521                 torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE,
522                                               "ldb_msg_add_empty() failed");
523
524                 ldb_err = ldb_add(priv->ldb_ctx, msg);
525                 torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE, "ldb_add() failed");
526         }
527
528 DONE:
529         if (fd != -1) {
530                 close(fd);
531                 unlink(ldb_url);
532         }
533         talloc_free(mem_ctx);
534         return bret;
535 }
536
537 /*
538  * Setup/Teardown for test case
539  */
540 static bool torture_drs_unit_prefixmap_setup(struct torture_context *tctx, struct drsut_prefixmap_data **priv)
541 {
542         WERROR werr;
543
544         *priv = talloc_zero(tctx, struct drsut_prefixmap_data);
545         torture_assert(tctx, *priv != NULL, "Not enough memory");
546
547         werr = _drsut_prefixmap_new(_prefixmap_test_new_data, ARRAY_SIZE(_prefixmap_test_new_data), tctx, &(*priv)->pfm_new);
548         torture_assert_werr_ok(tctx, werr, "failed to create pfm_new");
549
550         werr = _drsut_prefixmap_new(_prefixmap_full_map_data, ARRAY_SIZE(_prefixmap_full_map_data), tctx, &(*priv)->pfm_full);
551         torture_assert_werr_ok(tctx, werr, "failed to create pfm_test");
552
553         /* create temporary LDB and populate with data */
554         if (!torture_drs_unit_ldb_setup(tctx, *priv)) {
555                 return false;
556         }
557
558         return true;
559 }
560
561 static bool torture_drs_unit_prefixmap_teardown(struct torture_context *tctx, struct drsut_prefixmap_data *priv)
562 {
563         talloc_free(priv);
564
565         return true;
566 }
567
568 /**
569  * Test case initialization for
570  * DRS-UNIT.prefixMap
571  */
572 struct torture_tcase * torture_drs_unit_prefixmap(struct torture_suite *suite)
573 {
574         typedef bool (*pfn_setup)(struct torture_context *, void **);
575         typedef bool (*pfn_teardown)(struct torture_context *, void *);
576         typedef bool (*pfn_run)(struct torture_context *, void *);
577
578         struct torture_tcase * tc = torture_suite_add_tcase(suite, "prefixMap");
579
580         torture_tcase_set_fixture(tc,
581                                   (pfn_setup)torture_drs_unit_prefixmap_setup,
582                                   (pfn_teardown)torture_drs_unit_prefixmap_teardown);
583
584         tc->description = talloc_strdup(tc, "Unit tests for DRSUAPI::prefixMap implementation");
585
586         torture_tcase_add_simple_test(tc, "new", (pfn_run)torture_drs_unit_pfm_new);
587
588         torture_tcase_add_simple_test(tc, "make_attid_full_map", (pfn_run)torture_drs_unit_pfm_make_attid_full_map);
589         torture_tcase_add_simple_test(tc, "make_attid_small_map", (pfn_run)torture_drs_unit_pfm_make_attid_small_map);
590         torture_tcase_add_simple_test(tc, "oid_from_attid_full_map", (pfn_run)torture_drs_unit_pfm_oid_from_attid);
591
592         torture_tcase_add_simple_test(tc, "pfm_to_from_drsuapi", (pfn_run)torture_drs_unit_pfm_to_from_drsuapi);
593
594         torture_tcase_add_simple_test(tc, "pfm_to_from_ldb_val", (pfn_run)torture_drs_unit_pfm_to_from_ldb_val);
595
596         return tc;
597 }