LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules - schema_load.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 215 283 76.0 %
Date: 2024-04-21 15:09:00 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS Implementation.
       3             : 
       4             :    The module that handles the Schema FSMO Role Owner
       5             :    checkings, it also loads the dsdb_schema.
       6             :    
       7             :    Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
       8             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009-2010
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             :    
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             :    
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             :    
      23             : */
      24             : 
      25             : #include "includes.h"
      26             : #include "ldb_module.h"
      27             : #include "dsdb/samdb/samdb.h"
      28             : #include "librpc/gen_ndr/ndr_misc.h"
      29             : #include "librpc/gen_ndr/ndr_drsuapi.h"
      30             : #include "librpc/gen_ndr/ndr_drsblobs.h"
      31             : #include "param/param.h"
      32             : #include <tdb.h>
      33             : #include "lib/tdb_wrap/tdb_wrap.h"
      34             : #include "dsdb/samdb/ldb_modules/util.h"
      35             : #include "lib/ldb-samba/ldb_wrap.h"
      36             : #include "lib/util/smb_strtox.h"
      37             : 
      38             : #include "system/filesys.h"
      39             : struct schema_load_private_data {
      40             :         struct ldb_module *module;
      41             :         uint64_t in_transaction;
      42             :         uint64_t in_read_transaction;
      43             :         struct tdb_wrap *metadata;
      44             :         uint64_t schema_seq_num_cache;
      45             :         int tdb_seqnum;
      46             : 
      47             :         /*
      48             :          * Please write out the updated schema on the next transaction
      49             :          * start
      50             :          */
      51             :         bool need_write;
      52             : };
      53             : 
      54             : static int dsdb_schema_from_db(struct ldb_module *module,
      55             :                                TALLOC_CTX *mem_ctx,
      56             :                                uint64_t schema_seq_num,
      57             :                                struct dsdb_schema **schema);
      58             : 
      59             : /*
      60             :  * Open sam.ldb.d/metadata.tdb.
      61             :  */
      62      182004 : static int schema_metadata_open(struct ldb_module *module)
      63             : {
      64      182004 :         struct schema_load_private_data *data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
      65      182004 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
      66        6016 :         TALLOC_CTX *tmp_ctx;
      67        6016 :         struct loadparm_context *lp_ctx;
      68        6016 :         char *filename;
      69        6016 :         int open_flags;
      70        6016 :         struct stat statbuf;
      71             : 
      72      182004 :         if (!data) {
      73           0 :                 return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
      74             :                                         "schema_load: metadata not initialized");
      75             :         }
      76      182004 :         data->metadata = NULL;
      77             : 
      78      182004 :         tmp_ctx = talloc_new(NULL);
      79      182004 :         if (tmp_ctx == NULL) {
      80           0 :                 return ldb_module_oom(module);
      81             :         }
      82             : 
      83      182004 :         filename = ldb_relative_path(ldb,
      84             :                                      tmp_ctx,
      85             :                                      "sam.ldb.d/metadata.tdb");
      86      182004 :         if (filename == NULL) {
      87           0 :                 talloc_free(tmp_ctx);
      88           0 :                 return ldb_module_oom(module);
      89             :         }
      90             : 
      91      182004 :         open_flags = O_RDWR;
      92      182004 :         if (stat(filename, &statbuf) != 0) {
      93           0 :                 talloc_free(tmp_ctx);
      94           0 :                 return LDB_ERR_OPERATIONS_ERROR;
      95             :         }
      96             : 
      97      182004 :         lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
      98             :                                        struct loadparm_context);
      99             : 
     100      182004 :         data->metadata = tdb_wrap_open(data, filename, 10,
     101             :                                        lpcfg_tdb_flags(lp_ctx, TDB_DEFAULT|TDB_SEQNUM),
     102             :                                        open_flags, 0660);
     103      182004 :         if (data->metadata == NULL) {
     104           0 :                 talloc_free(tmp_ctx);
     105           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     106             :         }
     107             : 
     108      182004 :         talloc_free(tmp_ctx);
     109      182004 :         return LDB_SUCCESS;
     110             : }
     111             : 
     112    46338257 : static int schema_metadata_get_uint64(struct schema_load_private_data *data,
     113             :                                          const char *key, uint64_t *value,
     114             :                                          uint64_t default_value)
     115             : {
     116     3973124 :         struct tdb_context *tdb;
     117     3973124 :         TDB_DATA tdb_key, tdb_data;
     118     3973124 :         char *value_str;
     119     3973124 :         TALLOC_CTX *tmp_ctx;
     120     3973124 :         int tdb_seqnum;
     121    46338257 :         int error = 0;
     122             : 
     123    46338257 :         if (!data) {
     124           0 :                 *value = default_value;
     125           0 :                 return LDB_SUCCESS;
     126             :         }
     127             : 
     128    46338257 :         if (!data->metadata) {
     129           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     130             :         }
     131             : 
     132    46338257 :         tdb_seqnum = tdb_get_seqnum(data->metadata->tdb);
     133    46338257 :         if (tdb_seqnum == data->tdb_seqnum) {
     134    41441800 :                 *value = data->schema_seq_num_cache;
     135    41441800 :                 return LDB_SUCCESS;
     136             :         }
     137             : 
     138     4896457 :         tmp_ctx = talloc_new(NULL);
     139     4896457 :         if (tmp_ctx == NULL) {
     140           0 :                 return ldb_module_oom(data->module);
     141             :         }
     142             : 
     143     4896457 :         tdb = data->metadata->tdb;
     144             : 
     145     4896457 :         tdb_key.dptr = (uint8_t *)discard_const_p(char, key);
     146     4896457 :         tdb_key.dsize = strlen(key);
     147             : 
     148     4896457 :         tdb_data = tdb_fetch(tdb, tdb_key);
     149     4896457 :         if (!tdb_data.dptr) {
     150     4444396 :                 if (tdb_error(tdb) == TDB_ERR_NOEXIST) {
     151     4444396 :                         *value = default_value;
     152     4444396 :                         talloc_free(tmp_ctx);
     153     4444396 :                         return LDB_SUCCESS;
     154             :                 } else {
     155           0 :                         talloc_free(tmp_ctx);
     156           0 :                         return ldb_module_error(data->module, LDB_ERR_OPERATIONS_ERROR,
     157             :                                                 tdb_errorstr(tdb));
     158             :                 }
     159             :         }
     160             : 
     161      452061 :         value_str = talloc_strndup(tmp_ctx, (char *)tdb_data.dptr, tdb_data.dsize);
     162      452061 :         if (value_str == NULL) {
     163           0 :                 SAFE_FREE(tdb_data.dptr);
     164           0 :                 talloc_free(tmp_ctx);
     165           0 :                 return ldb_module_oom(data->module);
     166             :         }
     167             : 
     168             :         /*
     169             :          * Now store it in the cache.  We don't mind that tdb_seqnum
     170             :          * may be stale now, that just means the cache won't be used
     171             :          * next time
     172             :          */
     173      452061 :         data->tdb_seqnum = tdb_seqnum;
     174      452061 :         data->schema_seq_num_cache = smb_strtoull(value_str,
     175             :                                                   NULL,
     176             :                                                   10,
     177             :                                                   &error,
     178             :                                                   SMB_STR_STANDARD);
     179      452061 :         if (error != 0) {
     180           0 :                 talloc_free(tmp_ctx);
     181           0 :                 return ldb_module_error(data->module, LDB_ERR_OPERATIONS_ERROR,
     182             :                                         "Failed to convert value");
     183             :         }
     184             : 
     185      452061 :         *value = data->schema_seq_num_cache;
     186             : 
     187      452061 :         SAFE_FREE(tdb_data.dptr);
     188      452061 :         talloc_free(tmp_ctx);
     189             : 
     190      452061 :         return LDB_SUCCESS;
     191             : }
     192             : 
     193   164100270 : static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct tevent_context *ev,
     194             :                                                struct dsdb_schema *schema, bool is_global_schema)
     195             : {
     196    10786447 :         TALLOC_CTX *mem_ctx;
     197   164100270 :         uint64_t schema_seq_num = 0;
     198    10786447 :         int ret;
     199   164100270 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     200    10786447 :         struct dsdb_schema *new_schema;
     201             :         
     202   164100270 :         struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
     203   164100270 :         if (!private_data) {
     204             :                 /* We can't refresh until the init function has run */
     205           0 :                 return schema;
     206             :         }
     207             : 
     208   164100270 :         if (schema != NULL) {
     209             :                 /*
     210             :                  * If we have a schema already (not in the startup)
     211             :                  * and we are in a read or write transaction, then
     212             :                  * avoid a schema reload, it can't have changed
     213             :                  */
     214   164090276 :                 if (private_data->in_transaction > 0
     215   108337510 :                     || private_data->in_read_transaction > 0 ) {
     216             :                         /*
     217             :                          * If the refresh is not an expected part of a
     218             :                          * larger transaction, then we don't allow a
     219             :                          * schema reload during a transaction. This
     220             :                          * stops others from modifying our schema
     221             :                          * behind our backs
     222             :                          */
     223   118346108 :                         if (ldb_get_opaque(ldb,
     224             :                                            "dsdb_schema_refresh_expected")
     225             :                             != (void *)1) {
     226   110948690 :                                 return schema;
     227             :                         }
     228             :                 }
     229             :         }
     230             : 
     231    46338257 :         SMB_ASSERT(ev == ldb_get_event_context(ldb));
     232             : 
     233    46338257 :         mem_ctx = talloc_new(module);
     234    46338257 :         if (mem_ctx == NULL) {
     235           0 :                 return NULL;
     236             :         }
     237             : 
     238             :         /*
     239             :          * We update right now the last refresh timestamp so that if
     240             :          * the schema partition hasn't change we don't keep on retrying.
     241             :          * Otherwise if the timestamp was update only when the schema has
     242             :          * actually changed (and therefore completely reloaded) we would
     243             :          * continue to hit the database to get the highest USN.
     244             :          */
     245             : 
     246    46338257 :         ret = schema_metadata_get_uint64(private_data,
     247             :                                          DSDB_METADATA_SCHEMA_SEQ_NUM,
     248             :                                          &schema_seq_num, 0);
     249             : 
     250    46338257 :         if (schema != NULL) {
     251    46328263 :                 if (ret == LDB_SUCCESS) {
     252    46328263 :                         if (schema->metadata_usn == schema_seq_num) {
     253    46310599 :                                 TALLOC_FREE(mem_ctx);
     254    46310599 :                                 return schema;
     255             :                         } else {
     256       17664 :                                 DEBUG(3, ("Schema refresh needed %lld != %lld\n",
     257             :                                           (unsigned long long)schema->metadata_usn,
     258             :                                           (unsigned long long)schema_seq_num));
     259             :                         }
     260             :                 } else {
     261             :                         /* From an old provision it can happen that the tdb didn't exists yet */
     262           0 :                         DEBUG(0, ("Error while searching for the schema usn in the metadata ignoring: %d:%s:%s\n",
     263             :                               ret, ldb_strerror(ret), ldb_errstring(ldb)));
     264           0 :                         TALLOC_FREE(mem_ctx);
     265           0 :                         return schema;
     266             :                 }
     267             :         } else {
     268        9994 :                 DEBUG(10, ("Initial schema load needed, as we have no existing schema, seq_num: %lld\n",
     269             :                           (unsigned long long)schema_seq_num));
     270             :         }
     271             : 
     272       27658 :         ret = dsdb_schema_from_db(module, mem_ctx, schema_seq_num, &new_schema);
     273       27658 :         if (ret != LDB_SUCCESS) {
     274           0 :                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     275             :                               "dsdb_schema_from_db() failed: %d:%s: %s",
     276             :                               ret, ldb_strerror(ret), ldb_errstring(ldb));
     277           0 :                 TALLOC_FREE(mem_ctx);
     278           0 :                 return schema;
     279             :         }
     280             : 
     281       27658 :         ret = dsdb_set_schema(ldb, new_schema, SCHEMA_MEMORY_ONLY);
     282       27658 :         if (ret != LDB_SUCCESS) {
     283           0 :                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     284             :                               "dsdb_set_schema() failed: %d:%s: %s",
     285             :                               ret, ldb_strerror(ret), ldb_errstring(ldb));
     286           0 :                 TALLOC_FREE(mem_ctx);
     287           0 :                 return schema;
     288             :         }
     289       27658 :         if (is_global_schema) {
     290       20086 :                 dsdb_make_schema_global(ldb, new_schema);
     291             :         }
     292       27658 :         TALLOC_FREE(mem_ctx);
     293       27658 :         return new_schema;
     294             : }
     295             : 
     296             : 
     297             : /*
     298             :   Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
     299             : */
     300             : 
     301       27716 : static int dsdb_schema_from_db(struct ldb_module *module,
     302             :                                TALLOC_CTX *mem_ctx,
     303             :                                uint64_t schema_seq_num,
     304             :                                struct dsdb_schema **schema)
     305             : {
     306       27716 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     307         316 :         TALLOC_CTX *tmp_ctx;
     308         316 :         char *error_string;
     309         316 :         int ret, i;
     310       27716 :         struct ldb_dn *schema_dn = ldb_get_schema_basedn(ldb);
     311         316 :         struct ldb_result *res;
     312       27716 :         struct ldb_message *schema_msg = NULL;
     313         316 :         static const char *schema_attrs[] = {
     314             :                 DSDB_SCHEMA_COMMON_ATTRS,
     315             :                 DSDB_SCHEMA_ATTR_ATTRS,
     316             :                 DSDB_SCHEMA_CLASS_ATTRS,
     317             :                 "prefixMap",
     318             :                 "schemaInfo",
     319             :                 "fSMORoleOwner",
     320             :                 NULL
     321             :         };
     322         316 :         unsigned flags;
     323             : 
     324       27716 :         tmp_ctx = talloc_new(module);
     325       27716 :         if (!tmp_ctx) {
     326           0 :                 return ldb_oom(ldb);
     327             :         }
     328             : 
     329             :         /* we don't want to trace the schema load */
     330       27716 :         flags = ldb_get_flags(ldb);
     331       27716 :         ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
     332             : 
     333             :         /*
     334             :          * Load the attribute and class definitions, as well as
     335             :          * the schema object. We do this in one search and then
     336             :          * split it so that there isn't a race condition when
     337             :          * the schema is changed between two searches.
     338             :          */
     339       27716 :         ret = dsdb_module_search(module, tmp_ctx, &res,
     340             :                                  schema_dn, LDB_SCOPE_SUBTREE,
     341             :                                  schema_attrs,
     342             :                                  DSDB_FLAG_NEXT_MODULE |
     343             :                                  DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
     344             :                                  NULL,
     345             :                                  "(|(objectClass=attributeSchema)"
     346             :                                  "(objectClass=classSchema)"
     347             :                                  "(objectClass=dMD))");
     348       27716 :         if (ret != LDB_SUCCESS) {
     349           0 :                 ldb_asprintf_errstring(ldb, 
     350             :                                        "dsdb_schema: failed to search attributeSchema and classSchema objects: %s",
     351             :                                        ldb_errstring(ldb));
     352           0 :                 goto failed;
     353             :         }
     354             : 
     355             :         /*
     356             :          * Separate the schema object from the attribute and
     357             :          * class objects.
     358             :          */
     359    19737763 :         for (i = 0; i < res->count; i++) {
     360    19737763 :                 if (ldb_msg_find_element(res->msgs[i], "prefixMap")) {
     361       27716 :                         schema_msg = res->msgs[i];
     362       27716 :                         break;
     363             :                 }
     364             :         }
     365             : 
     366       27716 :         if (schema_msg == NULL) {
     367           0 :                 ldb_asprintf_errstring(ldb,
     368             :                                        "dsdb_schema load failed: failed to find prefixMap");
     369           0 :                 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
     370           0 :                 goto failed;
     371             :         }
     372             : 
     373       27716 :         ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
     374             :                                            schema_msg, res, schema, &error_string);
     375       27716 :         if (ret != LDB_SUCCESS) {
     376           0 :                 ldb_asprintf_errstring(ldb, 
     377             :                                        "dsdb_schema load failed: %s",
     378             :                                        error_string);
     379           0 :                 goto failed;
     380             :         }
     381             : 
     382       27716 :         (*schema)->metadata_usn = schema_seq_num;
     383             : 
     384       27716 :         talloc_steal(mem_ctx, *schema);
     385             : 
     386       27716 : failed:
     387       27716 :         if (flags & LDB_FLG_ENABLE_TRACING) {
     388           0 :                 flags = ldb_get_flags(ldb);
     389           0 :                 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
     390             :         }
     391       27716 :         talloc_free(tmp_ctx);
     392       27716 :         return ret;
     393             : }       
     394             : 
     395      182004 : static int schema_load(struct ldb_context *ldb,
     396             :                        struct ldb_module *module,
     397             :                        bool *need_write)
     398             : {
     399        6016 :         struct dsdb_schema *schema;
     400        6016 :         int ret, metadata_ret;
     401      182004 :         TALLOC_CTX *frame = talloc_stackframe();
     402             :         
     403      182004 :         schema = dsdb_get_schema(ldb, frame);
     404             : 
     405      182004 :         metadata_ret = schema_metadata_open(module);
     406             : 
     407             :         /* We might already have a schema */
     408      182004 :         if (schema != NULL) {
     409             :                 /* If we have the metadata.tdb, then hook up the refresh function */
     410      174111 :                 if (metadata_ret == LDB_SUCCESS && dsdb_uses_global_schema(ldb)) {
     411      173906 :                         ret = dsdb_set_schema_refresh_function(ldb, dsdb_schema_refresh, module);
     412             : 
     413      173906 :                         if (ret != LDB_SUCCESS) {
     414           0 :                                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     415             :                                               "schema_load_init: dsdb_set_schema_refresh_fns() failed: %d:%s: %s",
     416             :                                               ret, ldb_strerror(ret), ldb_errstring(ldb));
     417           0 :                                 TALLOC_FREE(frame);
     418           0 :                                 return ret;
     419             :                         }
     420             :                 }
     421             : 
     422      174111 :                 TALLOC_FREE(frame);
     423      174111 :                 return LDB_SUCCESS;
     424             :         }
     425             : 
     426        7893 :         if (metadata_ret == LDB_SUCCESS) {
     427        7893 :                 ret = dsdb_set_schema_refresh_function(ldb, dsdb_schema_refresh, module);
     428             : 
     429        7893 :                 if (ret != LDB_SUCCESS) {
     430           0 :                         ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     431             :                                       "schema_load_init: dsdb_set_schema_refresh_fns() failed: %d:%s: %s",
     432             :                                       ret, ldb_strerror(ret), ldb_errstring(ldb));
     433           0 :                         TALLOC_FREE(frame);
     434           0 :                         return ret;
     435             :                 }
     436             :         } else {
     437           0 :                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     438             :                               "schema_load_init: failed to open metadata.tdb");
     439           0 :                 TALLOC_FREE(frame);
     440           0 :                 return metadata_ret;
     441             :         }
     442             : 
     443        7893 :         schema = dsdb_get_schema(ldb, frame);
     444             : 
     445             :         /* We do this, invoking the refresh handler, so we know that it works */
     446        7893 :         if (schema == NULL) {
     447           0 :                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     448             :                               "schema_load_init: dsdb_get_schema failed");
     449           0 :                 TALLOC_FREE(frame);
     450           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     451             :         }
     452             : 
     453             :         /* Now check the @INDEXLIST is correct, or fix it up */
     454        7893 :         ret = dsdb_schema_set_indices_and_attributes(ldb, schema,
     455             :                                                      SCHEMA_COMPARE);
     456        7893 :         if (ret == LDB_ERR_BUSY) {
     457          37 :                 *need_write = true;
     458          37 :                 ret = LDB_SUCCESS;
     459             :         } else {
     460        7856 :                 *need_write = false;
     461             :         }
     462             : 
     463        7893 :         if (ret != LDB_SUCCESS) {
     464           0 :                 ldb_asprintf_errstring(ldb, "Failed to update "
     465             :                                        "@INDEXLIST and @ATTRIBUTES "
     466             :                                        "records to match database schema: %s",
     467             :                                        ldb_errstring(ldb));
     468           0 :                 TALLOC_FREE(frame);
     469           0 :                 return ret;
     470             :         }
     471             : 
     472        7893 :         TALLOC_FREE(frame);
     473        7675 :         return LDB_SUCCESS;
     474             : }
     475             : 
     476      182004 : static int schema_load_init(struct ldb_module *module)
     477             : {
     478      182004 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     479        6016 :         struct schema_load_private_data *private_data =
     480      182004 :                 talloc_get_type_abort(ldb_module_get_private(module),
     481             :                                       struct schema_load_private_data);
     482        6016 :         int ret;
     483             : 
     484      182004 :         ret = ldb_next_init(module);
     485      182004 :         if (ret != LDB_SUCCESS) {
     486           0 :                 return ret;
     487             :         }
     488             : 
     489      182004 :         return schema_load(ldb, module, &private_data->need_write);
     490             : }
     491             : 
     492      348865 : static int schema_load_start_transaction(struct ldb_module *module)
     493             : {
     494        2179 :         struct schema_load_private_data *private_data =
     495      348865 :                 talloc_get_type_abort(ldb_module_get_private(module),
     496             :                                       struct schema_load_private_data);
     497      348865 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     498        2179 :         struct dsdb_schema *schema;
     499        2179 :         int ret;
     500             : 
     501      348865 :         ret = ldb_next_start_trans(module);
     502      348865 :         if (ret != LDB_SUCCESS) {
     503           0 :                 return ret;
     504             :         }
     505             : 
     506             :         /* Try the schema refresh now */
     507      348865 :         schema = dsdb_get_schema(ldb, NULL);
     508      348865 :         if (schema == NULL) {
     509           0 :                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     510             :                               "schema_load_init: dsdb_get_schema failed");
     511           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     512             :         }
     513             : 
     514      348865 :         if (private_data->need_write) {
     515          33 :                 ret = dsdb_schema_set_indices_and_attributes(ldb,
     516             :                                                              schema,
     517             :                                                              SCHEMA_WRITE);
     518          33 :                 private_data->need_write = false;
     519             :         }
     520             : 
     521      348865 :         private_data->in_transaction++;
     522             : 
     523      348865 :         return ret;
     524             : }
     525             : 
     526      303805 : static int schema_load_end_transaction(struct ldb_module *module)
     527             : {
     528        2174 :         struct schema_load_private_data *private_data =
     529      303805 :                 talloc_get_type_abort(ldb_module_get_private(module),
     530             :                                       struct schema_load_private_data);
     531      303805 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     532             : 
     533      303805 :         if (private_data->in_transaction == 0) {
     534           0 :                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     535             :                               "schema_load_end_transaction: transaction mismatch");
     536           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     537             :         }
     538      303805 :         private_data->in_transaction--;
     539             : 
     540      303805 :         return ldb_next_end_trans(module);
     541             : }
     542             : 
     543       45058 : static int schema_load_del_transaction(struct ldb_module *module)
     544             : {
     545           4 :         struct schema_load_private_data *private_data =
     546       45058 :                 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
     547       45058 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     548             : 
     549       45058 :         if (private_data->in_transaction == 0) {
     550           0 :                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
     551             :                               "schema_load_del_transaction: transaction mismatch");
     552           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     553             :         }
     554       45058 :         private_data->in_transaction--;
     555             : 
     556       45058 :         return ldb_next_del_trans(module);
     557             : }
     558             : 
     559             : /* This is called in a transaction held by the callers */
     560     1649244 : static int schema_load_extended(struct ldb_module *module, struct ldb_request *req)
     561             : {
     562     1649244 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     563       95828 :         struct dsdb_schema *schema;
     564       95828 :         int ret;
     565             : 
     566     1649244 :         if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_LOAD) == 0) {
     567             : 
     568          58 :                 ret = dsdb_schema_from_db(module, req, 0, &schema);
     569          58 :                 if (ret == LDB_SUCCESS) {
     570          58 :                         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
     571             :                 }
     572           0 :                 return ret;
     573             : 
     574     1649186 :         } else if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) == 0) {
     575             :                 /* Force a refresh */
     576         761 :                 schema = dsdb_get_schema(ldb, NULL);
     577             : 
     578         761 :                 ret = dsdb_schema_set_indices_and_attributes(ldb,
     579             :                                                              schema,
     580             :                                                              SCHEMA_WRITE);
     581             : 
     582         761 :                 if (ret != LDB_SUCCESS) {
     583           0 :                         ldb_asprintf_errstring(ldb, "Failed to write new "
     584             :                                                "@INDEXLIST and @ATTRIBUTES "
     585             :                                                "records for updated schema: %s",
     586             :                                                ldb_errstring(ldb));
     587           0 :                         return ret;
     588             :                 }
     589             : 
     590         761 :                 return ldb_next_request(module, req);
     591             :         } else {
     592             :                 /* Pass to next module, the partition one should finish the chain */
     593     1648425 :                 return ldb_next_request(module, req);
     594             :         }
     595             : }
     596             : 
     597    18823384 : static int schema_read_lock(struct ldb_module *module)
     598             : {
     599     1115282 :         struct schema_load_private_data *private_data =
     600    18823384 :                 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
     601     1115282 :         int ret;
     602             : 
     603    18823384 :         if (private_data == NULL) {
     604      182004 :                 private_data = talloc_zero(module, struct schema_load_private_data);
     605      182004 :                 if (private_data == NULL) {
     606           0 :                         return ldb_module_oom(module);
     607             :                 }
     608             : 
     609      182004 :                 private_data->module = module;
     610             : 
     611      182004 :                 ldb_module_set_private(module, private_data);
     612             :         }
     613             : 
     614    18823384 :         ret = ldb_next_read_lock(module);
     615    18823384 :         if (ret != LDB_SUCCESS) {
     616           0 :                 return ret;
     617             :         }
     618             : 
     619    18823384 :         if (private_data->in_transaction == 0 &&
     620    11965321 :             private_data->in_read_transaction == 0) {
     621             :                 /* Try the schema refresh now */
     622     9882033 :                 dsdb_get_schema(ldb_module_get_ctx(module), NULL);
     623             :         }
     624             : 
     625    18823384 :         private_data->in_read_transaction++;
     626             : 
     627    18823384 :         return LDB_SUCCESS;
     628             : }
     629             : 
     630    18823384 : static int schema_read_unlock(struct ldb_module *module)
     631             : {
     632     1115282 :         struct schema_load_private_data *private_data =
     633    18823384 :                 talloc_get_type_abort(ldb_module_get_private(module),
     634             :                                       struct schema_load_private_data);
     635             : 
     636    18823384 :         private_data->in_read_transaction--;
     637             : 
     638    18823384 :         return ldb_next_read_unlock(module);
     639             : }
     640             : 
     641             : 
     642             : static const struct ldb_module_ops ldb_schema_load_module_ops = {
     643             :         .name           = "schema_load",
     644             :         .init_context   = schema_load_init,
     645             :         .extended       = schema_load_extended,
     646             :         .start_transaction = schema_load_start_transaction,
     647             :         .end_transaction   = schema_load_end_transaction,
     648             :         .del_transaction   = schema_load_del_transaction,
     649             :         .read_lock      = schema_read_lock,
     650             :         .read_unlock    = schema_read_unlock,
     651             : };
     652             : 
     653        6040 : int ldb_schema_load_module_init(const char *version)
     654             : {
     655        6040 :         LDB_MODULE_CHECK_VERSION(version);
     656        6040 :         return ldb_register_module(&ldb_schema_load_module_ops);
     657             : }

Generated by: LCOV version 1.14