LCOV - code coverage report
Current view: top level - source4/torture/drs/unit - schemainfo_tests.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 11 224 4.9 %
Date: 2024-06-13 04:01:37 Functions: 1 13 7.7 %

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

Generated by: LCOV version 1.13