s4-dsdb: pass parent request to dsdb_module_*() functions
[samba.git] / source4 / torture / drs / unit / schemainfo_tests.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    DRSUAPI schemaInfo unit tests
5
6    Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2010
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 "dsdb/samdb/ldb_modules/util.h"
27 #include "ldb_wrap.h"
28 #include "lib/ldb/include/ldb_module.h"
29 #include "torture/rpc/drsuapi.h"
30 #include "librpc/ndr/libndr.h"
31 #include "param/param.h"
32
33
34 /**
35  * schemaInfo to init ldb context with
36  *   Rev:  0
37  *   GUID: 00000000-0000-0000-0000-000000000000
38  */
39 #define SCHEMA_INFO_INIT_STR            "FF0000000000000000000000000000000000000000"
40
41 /**
42  * Default schema_info string to be used for testing
43  *   Rev:  01
44  *   GUID: 071c82fd-45c7-4351-a3db-51f75a630a7f
45  */
46 #define SCHEMA_INFO_DEFAULT_STR         "FF00000001FD821C07C7455143A3DB51F75A630A7F"
47
48 /**
49  * Schema info data to test with
50  */
51 struct schemainfo_data {
52         DATA_BLOB       ndr_blob;
53         struct dsdb_schema_info schi;
54         WERROR          werr_expected;
55         bool            test_both_ways;
56 };
57
58 /**
59  * Schema info test data in human-readable format (... kind of)
60  */
61 static const struct {
62         const char      *schema_info_str;
63         uint32_t        revision;
64         const char      *guid_str;
65         WERROR          werr_expected;
66         bool            test_both_ways;
67 } _schemainfo_test_data[] = {
68         {
69                 .schema_info_str = "FF0000000000000000000000000000000000000000",
70                 .revision = 0,
71                 .guid_str = "00000000-0000-0000-0000-000000000000",
72                 .werr_expected = WERR_OK,
73                 .test_both_ways = true
74         },
75         {
76                 .schema_info_str = "FF00000001FD821C07C7455143A3DB51F75A630A7F",
77                 .revision = 1,
78                 .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
79                 .werr_expected = WERR_OK,
80                 .test_both_ways = true
81         },
82         {
83                 .schema_info_str = "FFFFFFFFFFFD821C07C7455143A3DB51F75A630A7F",
84                 .revision = 0xFFFFFFFF,
85                 .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
86                 .werr_expected = WERR_OK,
87                 .test_both_ways = true
88         },
89         { /* len == 21 */
90                 .schema_info_str = "FF00000001FD821C07C7455143A3DB51F75A630A7F00",
91                 .revision = 1,
92                 .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
93                 .werr_expected = WERR_INVALID_PARAMETER,
94                 .test_both_ways = false
95         },
96         { /* marker == FF */
97                 .schema_info_str = "AA00000001FD821C07C7455143A3DB51F75A630A7F",
98                 .revision = 1,
99                 .guid_str = "071c82fd-45c7-4351-a3db-51f75a630a7f",
100                 .werr_expected = WERR_INVALID_PARAMETER,
101                 .test_both_ways = false
102         }
103 };
104
105 /**
106  * Private data to be shared among all test in Test case
107  */
108 struct drsut_schemainfo_data {
109         struct ldb_context *ldb;
110         struct ldb_module  *ldb_module;
111         struct dsdb_schema *schema;
112
113         /* Initial schemaInfo set in ldb to test with */
114         struct dsdb_schema_info *schema_info;
115
116         uint32_t test_data_count;
117         struct schemainfo_data *test_data;
118 };
119
120 /**
121  * torture macro to assert for equal dsdb_schema_info's
122  */
123 #define torture_assert_schema_info_equal(torture_ctx,got,expected,cmt)\
124         do { const struct dsdb_schema_info *__got = (got), *__expected = (expected); \
125         if (__got->revision != __expected->revision) { \
126                 torture_result(torture_ctx, TORTURE_FAIL, \
127                                __location__": "#got".revision %d did not match "#expected".revision %d: %s", \
128                                (int)__got->revision, (int)__expected->revision, cmt); \
129                 return false; \
130         } \
131         if (!GUID_equal(&__got->invocation_id, &__expected->invocation_id)) { \
132                 torture_result(torture_ctx, TORTURE_FAIL, \
133                                __location__": "#got".invocation_id did not match "#expected".invocation_id: %s", cmt); \
134                 return false; \
135         } \
136         } while(0)
137
138 /*
139  * forward declaration for internal functions
140  */
141 static bool _drsut_ldb_schema_info_reset(struct torture_context *tctx,
142                                          struct ldb_context *ldb,
143                                          const char *schema_info_str,
144                                          bool in_setup);
145
146
147 /**
148  * Creates dsdb_schema_info object based on NDR data
149  * passed as hex string
150  */
151 static bool _drsut_schemainfo_new(struct torture_context *tctx,
152                                   const char *schema_info_str, struct dsdb_schema_info **_si)
153 {
154         WERROR werr;
155         DATA_BLOB blob;
156
157         blob = strhex_to_data_blob(tctx, schema_info_str);
158         if (!blob.data) {
159                 torture_comment(tctx, "Not enough memory!\n");
160                 return false;
161         }
162
163         werr = dsdb_schema_info_from_blob(&blob, tctx, _si);
164         if (!W_ERROR_IS_OK(werr)) {
165                 torture_comment(tctx,
166                                 "Failed to create dsdb_schema_info object for %s: %s",
167                                 schema_info_str,
168                                 win_errstr(werr));
169                 return false;
170         }
171
172         data_blob_free(&blob);
173
174         return true;
175 }
176
177 /**
178  * Creates dsdb_schema_info object based on predefined data
179  * Function is public as it is intended to be used by other
180  * tests (e.g. prefixMap tests)
181  */
182 bool drsut_schemainfo_new(struct torture_context *tctx, struct dsdb_schema_info **_si)
183 {
184         return _drsut_schemainfo_new(tctx, SCHEMA_INFO_DEFAULT_STR, _si);
185 }
186
187
188 /*
189  * Tests dsdb_schema_info_new() and dsdb_schema_info_blob_new()
190  */
191 static bool test_dsdb_schema_info_new(struct torture_context *tctx,
192                                       struct drsut_schemainfo_data *priv)
193 {
194         WERROR werr;
195         DATA_BLOB ndr_blob;
196         DATA_BLOB ndr_blob_expected;
197         struct dsdb_schema_info *schi;
198         TALLOC_CTX *mem_ctx;
199
200         mem_ctx = talloc_new(priv);
201         torture_assert(tctx, mem_ctx, "Not enough memory!");
202         ndr_blob_expected = strhex_to_data_blob(mem_ctx, SCHEMA_INFO_INIT_STR);
203         torture_assert(tctx, ndr_blob_expected.data, "Not enough memory!");
204
205         werr = dsdb_schema_info_new(mem_ctx, &schi);
206         torture_assert_werr_ok(tctx, werr, "dsdb_schema_info_new() failed");
207         torture_assert_int_equal(tctx, schi->revision, 0,
208                                  "dsdb_schema_info_new() creates schemaInfo with invalid revision");
209         torture_assert(tctx, GUID_all_zero(&schi->invocation_id),
210                         "dsdb_schema_info_new() creates schemaInfo with not ZERO GUID");
211
212         werr = dsdb_schema_info_blob_new(mem_ctx, &ndr_blob);
213         torture_assert_werr_ok(tctx, werr, "dsdb_schema_info_blob_new() failed");
214         torture_assert_data_blob_equal(tctx, ndr_blob, ndr_blob_expected,
215                                        "dsdb_schema_info_blob_new() returned invalid blob");
216
217         talloc_free(mem_ctx);
218         return true;
219 }
220
221 /*
222  * Tests dsdb_schema_info_from_blob()
223  */
224 static bool test_dsdb_schema_info_from_blob(struct torture_context *tctx,
225                                             struct drsut_schemainfo_data *priv)
226 {
227         int i;
228         WERROR werr;
229         char *msg;
230         struct dsdb_schema_info *schema_info;
231         TALLOC_CTX *mem_ctx;
232
233         mem_ctx = talloc_new(priv);
234         torture_assert(tctx, mem_ctx, "Not enough memory!");
235
236         for (i = 0; i < priv->test_data_count; i++) {
237                 struct schemainfo_data *data = &priv->test_data[i];
238
239                 msg = talloc_asprintf(tctx, "dsdb_schema_info_from_blob() [%d]-[%s]",
240                                       i, _schemainfo_test_data[i].schema_info_str);
241
242                 werr = dsdb_schema_info_from_blob(&data->ndr_blob, mem_ctx, &schema_info);
243                 torture_assert_werr_equal(tctx, werr, data->werr_expected, msg);
244
245                 /* test returned data */
246                 if (W_ERROR_IS_OK(werr)) {
247                         torture_assert_schema_info_equal(tctx,
248                                                          schema_info, &data->schi,
249                                                          "after dsdb_schema_info_from_blob() call");
250                 }
251         }
252
253         talloc_free(mem_ctx);
254
255         return true;
256 }
257
258 /*
259  * Tests dsdb_blob_from_schema_info()
260  */
261 static bool test_dsdb_blob_from_schema_info(struct torture_context *tctx,
262                                             struct drsut_schemainfo_data *priv)
263 {
264         int i;
265         WERROR werr;
266         char *msg;
267         DATA_BLOB ndr_blob;
268         TALLOC_CTX *mem_ctx;
269
270         mem_ctx = talloc_new(priv);
271         torture_assert(tctx, mem_ctx, "Not enough memory!");
272
273         for (i = 0; i < priv->test_data_count; i++) {
274                 struct schemainfo_data *data = &priv->test_data[i];
275
276                 /* not all test are valid reverse type of conversion */
277                 if (!data->test_both_ways) {
278                         continue;
279                 }
280
281                 msg = talloc_asprintf(tctx, "dsdb_blob_from_schema_info() [%d]-[%s]",
282                                       i, _schemainfo_test_data[i].schema_info_str);
283
284                 werr = dsdb_blob_from_schema_info(&data->schi, mem_ctx, &ndr_blob);
285                 torture_assert_werr_equal(tctx, werr, data->werr_expected, msg);
286
287                 /* test returned data */
288                 if (W_ERROR_IS_OK(werr)) {
289                         torture_assert_data_blob_equal(tctx,
290                                                        ndr_blob, data->ndr_blob,
291                                                        "dsdb_blob_from_schema_info()");
292                 }
293         }
294
295         talloc_free(mem_ctx);
296
297         return true;
298 }
299
300 static bool test_dsdb_schema_info_cmp(struct torture_context *tctx,
301                                       struct drsut_schemainfo_data *priv)
302 {
303         DATA_BLOB blob;
304         struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
305
306         ctr = talloc_zero(priv, struct drsuapi_DsReplicaOIDMapping_Ctr);
307         torture_assert(tctx, ctr, "Not enough memory!");
308
309         /* not enough elements */
310         torture_assert_werr_equal(tctx,
311                                   dsdb_schema_info_cmp(priv->schema, ctr),
312                                   WERR_INVALID_PARAMETER,
313                                   "dsdb_schema_info_cmp(): unexpected result");
314
315         /* an empty element for schemaInfo */
316         ctr->num_mappings = 1;
317         ctr->mappings = talloc_zero_array(ctr, struct drsuapi_DsReplicaOIDMapping, 1);
318         torture_assert(tctx, ctr->mappings, "Not enough memory!");
319         torture_assert_werr_equal(tctx,
320                                   dsdb_schema_info_cmp(priv->schema, ctr),
321                                   WERR_INVALID_PARAMETER,
322                                   "dsdb_schema_info_cmp(): unexpected result");
323
324         /* test with invalid schemaInfo - length != 21 */
325         blob = strhex_to_data_blob(ctr, "FF00000001FD821C07C7455143A3DB51F75A630A7F00");
326         torture_assert(tctx, blob.data, "Not enough memory!");
327         ctr->mappings[0].oid.length     = blob.length;
328         ctr->mappings[0].oid.binary_oid = blob.data;
329         torture_assert_werr_equal(tctx,
330                                   dsdb_schema_info_cmp(priv->schema, ctr),
331                                   WERR_INVALID_PARAMETER,
332                                   "dsdb_schema_info_cmp(): unexpected result");
333
334         /* test with invalid schemaInfo - marker != 0xFF */
335         blob = strhex_to_data_blob(ctr, "AA00000001FD821C07C7455143A3DB51F75A630A7F");
336         torture_assert(tctx, blob.data, "Not enough memory!");
337         ctr->mappings[0].oid.length     = blob.length;
338         ctr->mappings[0].oid.binary_oid = blob.data;
339         torture_assert_werr_equal(tctx,
340                                   dsdb_schema_info_cmp(priv->schema, ctr),
341                                   WERR_INVALID_PARAMETER,
342                                   "dsdb_schema_info_cmp(): unexpected result");
343
344         /* test with valid schemaInfo, but not correct one */
345         blob = strhex_to_data_blob(ctr, "FF0000000000000000000000000000000000000000");
346         torture_assert(tctx, blob.data, "Not enough memory!");
347         ctr->mappings[0].oid.length     = blob.length;
348         ctr->mappings[0].oid.binary_oid = blob.data;
349         torture_assert_werr_equal(tctx,
350                                   dsdb_schema_info_cmp(priv->schema, ctr),
351                                   WERR_DS_DRA_SCHEMA_MISMATCH,
352                                   "dsdb_schema_info_cmp(): unexpected result");
353
354         /* test with correct schemaInfo, but invalid ATTID */
355         blob = strhex_to_data_blob(ctr, priv->schema->schema_info);
356         torture_assert(tctx, blob.data, "Not enough memory!");
357         ctr->mappings[0].id_prefix      = 1;
358         ctr->mappings[0].oid.length     = blob.length;
359         ctr->mappings[0].oid.binary_oid = blob.data;
360         torture_assert_werr_equal(tctx,
361                                   dsdb_schema_info_cmp(priv->schema, ctr),
362                                   WERR_INVALID_PARAMETER,
363                                   "dsdb_schema_info_cmp(): unexpected result");
364
365         /* test with valid schemaInfo */
366         blob = strhex_to_data_blob(ctr, priv->schema->schema_info);
367         ctr->mappings[0].id_prefix      = 0;
368         torture_assert_werr_ok(tctx,
369                                dsdb_schema_info_cmp(priv->schema, ctr),
370                                "dsdb_schema_info_cmp(): unexpected result");
371
372         talloc_free(ctr);
373         return true;
374 }
375
376 /*
377  * Tests dsdb_module_schema_info_blob_read()
378  *   and dsdb_module_schema_info_blob_write()
379  */
380 static bool test_dsdb_module_schema_info_blob_rw(struct torture_context *tctx,
381                                                 struct drsut_schemainfo_data *priv)
382 {
383         int ldb_err;
384         DATA_BLOB blob_write;
385         DATA_BLOB blob_read;
386
387         /* reset schmeInfo to know value */
388         torture_assert(tctx,
389                        _drsut_ldb_schema_info_reset(tctx, priv->ldb, SCHEMA_INFO_INIT_STR, false),
390                        "_drsut_ldb_schema_info_reset() failed");
391
392         /* write tests' default schemaInfo */
393         blob_write = strhex_to_data_blob(priv, SCHEMA_INFO_DEFAULT_STR);
394         torture_assert(tctx, blob_write.data, "Not enough memory!");
395
396         ldb_err = dsdb_module_schema_info_blob_write(priv->ldb_module,
397                                                      DSDB_FLAG_TOP_MODULE,
398                                                      &blob_write, NULL);
399         torture_assert_int_equal(tctx, ldb_err, LDB_SUCCESS, "dsdb_module_schema_info_blob_write() failed");
400
401         ldb_err = dsdb_module_schema_info_blob_read(priv->ldb_module, DSDB_FLAG_TOP_MODULE,
402                                                     priv, &blob_read, NULL);
403         torture_assert_int_equal(tctx, ldb_err, LDB_SUCCESS, "dsdb_module_schema_info_blob_read() failed");
404
405         /* check if we get what we wrote */
406         torture_assert_data_blob_equal(tctx, blob_read, blob_write,
407                                        "Write/Read of schemeInfo blob failed");
408
409         return true;
410 }
411
412 /*
413  * Tests dsdb_schema_update_schema_info()
414  */
415 static bool test_dsdb_module_schema_info_update(struct torture_context *tctx,
416                                                 struct drsut_schemainfo_data *priv)
417 {
418         int ldb_err;
419         WERROR werr;
420         DATA_BLOB blob;
421         struct dsdb_schema_info *schema_info;
422
423         /* reset schmeInfo to know value */
424         torture_assert(tctx,
425                        _drsut_ldb_schema_info_reset(tctx, priv->ldb, SCHEMA_INFO_INIT_STR, false),
426                        "_drsut_ldb_schema_info_reset() failed");
427
428         ldb_err = dsdb_module_schema_info_update(priv->ldb_module,
429                                                  priv->schema,
430                                                  DSDB_FLAG_TOP_MODULE | DSDB_FLAG_AS_SYSTEM, NULL);
431         torture_assert_int_equal(tctx, ldb_err, LDB_SUCCESS, "dsdb_module_schema_info_update() failed");
432
433         /* get updated schemaInfo */
434         ldb_err = dsdb_module_schema_info_blob_read(priv->ldb_module, DSDB_FLAG_TOP_MODULE,
435                                                     priv, &blob, NULL);
436         torture_assert_int_equal(tctx, ldb_err, LDB_SUCCESS, "dsdb_module_schema_info_blob_read() failed");
437
438         werr = dsdb_schema_info_from_blob(&blob, priv, &schema_info);
439         torture_assert_werr_ok(tctx, werr, "dsdb_schema_info_from_blob() failed");
440
441         /* check against default schema_info */
442         torture_assert_schema_info_equal(tctx, schema_info, priv->schema_info,
443                                           "schemaInfo attribute no updated correctly");
444
445         return true;
446 }
447
448
449 /**
450  * Reset schemaInfo record to know value
451  */
452 static bool _drsut_ldb_schema_info_reset(struct torture_context *tctx,
453                                          struct ldb_context *ldb,
454                                          const char *schema_info_str,
455                                          bool in_setup)
456 {
457         bool bret = true;
458         int ldb_err;
459         DATA_BLOB blob;
460         struct ldb_message *msg;
461         TALLOC_CTX *mem_ctx = talloc_new(tctx);
462
463         blob = strhex_to_data_blob(mem_ctx, schema_info_str);
464         torture_assert_goto(tctx, blob.data, bret, DONE, "Not enough memory!");
465
466         msg = ldb_msg_new(mem_ctx);
467         torture_assert_goto(tctx, msg, bret, DONE, "Not enough memory!");
468
469         msg->dn = ldb_get_schema_basedn(ldb);
470         ldb_err = ldb_msg_add_value(msg, "schemaInfo", &blob, NULL);
471         torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE,
472                                       "ldb_msg_add_value() failed");
473
474         if (in_setup) {
475                 ldb_err = ldb_add(ldb, msg);
476         } else {
477                 ldb_err = dsdb_replace(ldb, msg, DSDB_MODIFY_PERMISSIVE);
478         }
479         torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE,
480                                       "dsdb_replace() failed");
481
482 DONE:
483         talloc_free(mem_ctx);
484         return bret;
485 }
486
487 /**
488  * Prepare temporary LDB and opens it
489  */
490 static bool _drsut_ldb_setup(struct torture_context *tctx, struct drsut_schemainfo_data *priv)
491 {
492         int ldb_err;
493         char *ldb_url;
494         bool bret = true;
495         char *tempdir = NULL;
496         NTSTATUS status;
497         TALLOC_CTX* mem_ctx;
498
499         mem_ctx = talloc_new(priv);
500         torture_assert(tctx, mem_ctx, "Not enough memory!");
501
502         status = torture_temp_dir(tctx, "drs_", &tempdir);
503         torture_assert_ntstatus_ok_goto(tctx, status, bret, DONE, "creating temp dir");
504
505         ldb_url = talloc_asprintf(priv, "%s/drs_schemainfo.ldb", tempdir);
506         torture_assert_goto(tctx, ldb_url, bret, DONE, "Not enough memory!");
507
508         /* create LDB */
509         priv->ldb = ldb_wrap_connect(priv, tctx->ev, tctx->lp_ctx,
510                                      ldb_url, NULL, NULL, 0);
511         torture_assert_goto(tctx, priv->ldb, bret, DONE,  "ldb_wrap_connect() failed");
512
513         /* set some schemaNamingContext */
514         ldb_err = ldb_set_opaque(priv->ldb,
515                                  "schemaNamingContext",
516                                  ldb_dn_new(priv->ldb, priv->ldb, "CN=Schema,CN=Config"));
517         torture_assert_int_equal_goto(tctx, ldb_err, LDB_SUCCESS, bret, DONE,
518                                       "ldb_set_opaque() failed");
519
520         /* add schemaInfo attribute so tested layer could work properly */
521         torture_assert_goto(tctx,
522                             _drsut_ldb_schema_info_reset(tctx, priv->ldb, SCHEMA_INFO_INIT_STR, true),
523                             bret, DONE,
524                             "_drsut_ldb_schema_info_reset() failed");
525
526 DONE:
527         talloc_free(tempdir);
528         talloc_free(mem_ctx);
529         return bret;
530 }
531
532 /*
533  * Setup/Teardown for test case
534  */
535 static bool torture_drs_unit_schemainfo_setup(struct torture_context *tctx,
536                                               struct drsut_schemainfo_data **_priv)
537 {
538         int i;
539         int ldb_err;
540         NTSTATUS status;
541         DATA_BLOB ndr_blob;
542         struct GUID guid;
543         struct drsut_schemainfo_data *priv;
544
545         priv = talloc_zero(tctx, struct drsut_schemainfo_data);
546         torture_assert(tctx, priv, "Not enough memory!");
547
548         /* returned allocated pointer here
549          * teardown() will be called even in case of failure,
550          * so we'll get a changes to clean up  */
551         *_priv = priv;
552
553         /* create initial schemaInfo */
554         torture_assert(tctx,
555                        _drsut_schemainfo_new(tctx, SCHEMA_INFO_DEFAULT_STR, &priv->schema_info),
556                        "Failed to create schema_info test object");
557
558         /* create data to test with */
559         priv->test_data_count = ARRAY_SIZE(_schemainfo_test_data);
560         priv->test_data = talloc_array(tctx, struct schemainfo_data, priv->test_data_count);
561
562         for (i = 0; i < ARRAY_SIZE(_schemainfo_test_data); i++) {
563                 struct schemainfo_data *data = &priv->test_data[i];
564
565                 ndr_blob = strhex_to_data_blob(priv,
566                                                _schemainfo_test_data[i].schema_info_str);
567                 torture_assert(tctx, ndr_blob.data, "Not enough memory!");
568
569                 status = GUID_from_string(_schemainfo_test_data[i].guid_str, &guid);
570                 torture_assert_ntstatus_ok(tctx, status,
571                                            talloc_asprintf(tctx,
572                                                            "GUID_from_string() failed for %s",
573                                                            _schemainfo_test_data[i].guid_str));
574
575                 data->ndr_blob           = ndr_blob;
576                 data->schi.invocation_id = guid;
577                 data->schi.revision      = _schemainfo_test_data[i].revision;
578                 data->werr_expected      = _schemainfo_test_data[i].werr_expected;
579                 data->test_both_ways     = _schemainfo_test_data[i].test_both_ways;
580
581         }
582
583         /* create temporary LDB and populate with data */
584         if (!_drsut_ldb_setup(tctx, priv)) {
585                 return false;
586         }
587
588         /* create ldb_module mockup object */
589         priv->ldb_module = ldb_module_new(priv, priv->ldb, "schemaInfo_test_module", NULL);
590         torture_assert(tctx, priv->ldb_module, "Not enough memory!");
591
592         /* create schema mockup object */
593         priv->schema = dsdb_new_schema(priv);
594
595         /* set schema_info in dsdb_schema for testing */
596         priv->schema->schema_info = talloc_strdup(priv->schema, SCHEMA_INFO_DEFAULT_STR);
597
598         /* pre-cache invocationId for samdb_ntds_invocation_id()
599          * to work with our mock ldb */
600         ldb_err = ldb_set_opaque(priv->ldb, "cache.invocation_id",
601                                  &priv->schema_info->invocation_id);
602         torture_assert_int_equal(tctx, ldb_err, LDB_SUCCESS, "ldb_set_opaque() failed");
603
604         /* Perform all tests in transactions so that
605          * underlying modify calls not to fail */
606         ldb_err = ldb_transaction_start(priv->ldb);
607         torture_assert_int_equal(tctx,
608                                  ldb_err,
609                                  LDB_SUCCESS,
610                                  "ldb_transaction_start() failed");
611
612         return true;
613 }
614
615 static bool torture_drs_unit_schemainfo_teardown(struct torture_context *tctx,
616                                                  struct drsut_schemainfo_data *priv)
617 {
618         int ldb_err;
619
620         /* commit pending transaction so we will
621          * be able to check what LDB state is */
622         ldb_err = ldb_transaction_commit(priv->ldb);
623         if (ldb_err != LDB_SUCCESS) {
624                 torture_comment(tctx, "ldb_transaction_commit() - %s (%s)",
625                                 ldb_strerror(ldb_err),
626                                 ldb_errstring(priv->ldb));
627         }
628
629         talloc_free(priv);
630
631         return true;
632 }
633
634 /**
635  * Test case initialization for
636  * drs.unit.schemaInfo
637  */
638 struct torture_tcase * torture_drs_unit_schemainfo(struct torture_suite *suite)
639 {
640         typedef bool (*pfn_setup)(struct torture_context *, void **);
641         typedef bool (*pfn_teardown)(struct torture_context *, void *);
642         typedef bool (*pfn_run)(struct torture_context *, void *);
643
644         struct torture_tcase * tc = torture_suite_add_tcase(suite, "schemaInfo");
645
646         torture_tcase_set_fixture(tc,
647                                   (pfn_setup)torture_drs_unit_schemainfo_setup,
648                                   (pfn_teardown)torture_drs_unit_schemainfo_teardown);
649
650         tc->description = talloc_strdup(tc, "Unit tests for DRSUAPI::schemaInfo implementation");
651
652         torture_tcase_add_simple_test(tc, "dsdb_schema_info_new",
653                                       (pfn_run)test_dsdb_schema_info_new);
654         torture_tcase_add_simple_test(tc, "dsdb_schema_info_from_blob",
655                                       (pfn_run)test_dsdb_schema_info_from_blob);
656         torture_tcase_add_simple_test(tc, "dsdb_blob_from_schema_info",
657                                       (pfn_run)test_dsdb_blob_from_schema_info);
658         torture_tcase_add_simple_test(tc, "dsdb_schema_info_cmp",
659                                       (pfn_run)test_dsdb_schema_info_cmp);
660         torture_tcase_add_simple_test(tc, "dsdb_module_schema_info_blob read|write",
661                                       (pfn_run)test_dsdb_module_schema_info_blob_rw);
662         torture_tcase_add_simple_test(tc, "dsdb_module_schema_info_update",
663                                       (pfn_run)test_dsdb_module_schema_info_update);
664
665
666         return tc;
667 }