2 Unix SMB/CIFS mplementation.
4 The module that handles the Schema FSMO Role Owner
5 checkings, it also loads the dsdb_schema.
7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009-2010
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.
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.
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/>.
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 "lib/tdb_wrap/tdb_wrap.h"
33 #include "lib/tdb_compat/tdb_compat.h"
34 #include "dsdb/samdb/ldb_modules/util.h"
36 #include "system/filesys.h"
37 struct schema_load_private_data {
39 struct tdb_wrap *metadata;
42 static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_dn, uint64_t current_usn,
43 struct dsdb_schema **schema);
46 * Open sam.ldb.d/metadata.tdb.
48 static int schema_metadata_open(struct ldb_module *module)
50 struct schema_load_private_data *data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
51 struct ldb_context *ldb = ldb_module_get_ctx(module);
53 struct loadparm_context *lp_ctx;
60 return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
61 "schema_load: metadata not initialized");
63 data->metadata = NULL;
65 tmp_ctx = talloc_new(NULL);
66 if (tmp_ctx == NULL) {
67 return ldb_module_oom(module);
70 sam_name = (const char *)ldb_get_opaque(ldb, "ldb_url");
71 if (strncmp("tdb://", sam_name, 6) == 0) {
76 return ldb_operr(ldb);
78 filename = talloc_asprintf(tmp_ctx, "%s.d/metadata.tdb", sam_name);
85 if (stat(filename, &statbuf) != 0) {
87 return LDB_ERR_OPERATIONS_ERROR;
90 lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
91 struct loadparm_context);
93 data->metadata = tdb_wrap_open(data, filename, 10,
94 TDB_DEFAULT, open_flags, 0660,
96 if (data->metadata == NULL) {
98 return LDB_ERR_OPERATIONS_ERROR;
101 talloc_free(tmp_ctx);
105 static int schema_metadata_get_uint64(struct ldb_module *module,
106 const char *key, uint64_t *value,
107 uint64_t default_value)
109 struct schema_load_private_data *data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
110 struct tdb_context *tdb;
111 TDB_DATA tdb_key, tdb_data;
115 if (!data || !data->metadata) {
116 return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
117 "schema: metadata tdb not initialized");
120 tmp_ctx = talloc_new(NULL);
121 if (tmp_ctx == NULL) {
122 return ldb_module_oom(module);
125 tdb = data->metadata->tdb;
127 tdb_key.dptr = (uint8_t *)discard_const_p(char, key);
128 tdb_key.dsize = strlen(key);
130 tdb_data = tdb_fetch_compat(tdb, tdb_key);
131 if (!tdb_data.dptr) {
132 if (tdb_error(tdb) == TDB_ERR_NOEXIST) {
133 *value = default_value;
136 return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
137 tdb_errorstr_compat(tdb));
141 value_str = talloc_strndup(tmp_ctx, (char *)tdb_data.dptr, tdb_data.dsize);
142 if (value_str == NULL) {
143 SAFE_FREE(tdb_data.dptr);
144 talloc_free(tmp_ctx);
145 return ldb_module_oom(module);
148 *value = strtoull(value_str, NULL, 10);
150 SAFE_FREE(tdb_data.dptr);
151 talloc_free(tmp_ctx);
156 static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct dsdb_schema *schema, bool is_global_schema)
158 uint64_t current_usn, value;
160 struct ldb_result *res;
161 struct ldb_request *treq;
162 struct ldb_seqnum_request *tseq;
163 struct ldb_seqnum_result *tseqr;
164 struct dsdb_control_current_partition *ctrl;
165 struct ldb_context *ldb = ldb_module_get_ctx(module);
166 struct dsdb_schema *new_schema;
169 struct loadparm_context *lp_ctx =
170 (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm");
172 struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
174 /* We can't refresh until the init function has run */
178 /* We don't allow a schema reload during a transaction - nobody else can modify our schema behind our backs */
179 if (private_data->in_transaction) {
183 lastts = schema->last_refresh;
185 interval = lpcfg_parm_int(lp_ctx, NULL, "dsdb", "schema_reload_interval", 120);
186 if (lastts > (ts - interval)) {
187 DEBUG(11, ("Less than %d seconds since last reload, returning cached version ts = %d\n", interval, (int)lastts));
191 res = talloc_zero(schema, struct ldb_result);
195 tseq = talloc_zero(res, struct ldb_seqnum_request);
200 tseq->type = LDB_SEQ_HIGHEST_SEQ;
202 ret = ldb_build_extended_req(&treq, ldb_module_get_ctx(module), res,
203 LDB_EXTENDED_SEQUENCE_NUMBER,
207 ldb_extended_default_callback,
209 LDB_REQ_SET_LOCATION(treq);
210 if (ret != LDB_SUCCESS) {
216 * We update right now the last refresh timestamp so that if
217 * the schema partition hasn't change we don't keep on retrying.
218 * Otherwise if the timestamp was update only when the schema has
219 * actually changed (and therefor completely reloaded) we would
220 * continue to hit the database to get the highest USN.
223 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
224 if (ret == LDB_SUCCESS) {
225 schema->metadata_usn = value;
227 /* From an old provision it can happen that the tdb didn't exists yet */
228 DEBUG(0, ("Error while searching for the schema usn in the metadata\n"));
229 schema->metadata_usn = 0;
231 schema->last_refresh = ts;
233 ctrl = talloc(treq, struct dsdb_control_current_partition);
238 ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
239 ctrl->dn = schema->base_dn;
241 ret = ldb_request_add_control(treq,
242 DSDB_CONTROL_CURRENT_PARTITION_OID,
244 if (ret != LDB_SUCCESS) {
249 ret = ldb_next_request(module, treq);
250 if (ret != LDB_SUCCESS) {
254 ret = ldb_wait(treq->handle, LDB_WAIT_ALL);
255 if (ret != LDB_SUCCESS) {
259 tseqr = talloc_get_type(res->extended->data,
260 struct ldb_seqnum_result);
261 if (tseqr->seq_num == schema->reload_seq_number) {
266 schema->reload_seq_number = tseqr->seq_num;
269 ret = dsdb_module_load_partition_usn(module, schema->base_dn, ¤t_usn, NULL, NULL);
270 if (ret != LDB_SUCCESS || current_usn == schema->loaded_usn) {
274 ret = dsdb_schema_from_db(module, schema->base_dn, current_usn, &new_schema);
275 if (ret != LDB_SUCCESS) {
279 if (is_global_schema) {
280 dsdb_make_schema_global(ldb, new_schema);
287 Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
290 static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_dn, uint64_t current_usn,
291 struct dsdb_schema **schema)
293 struct ldb_context *ldb = ldb_module_get_ctx(module);
297 struct ldb_result *schema_res;
298 struct ldb_result *res;
299 static const char *schema_attrs[] = {
307 tmp_ctx = talloc_new(module);
312 /* we don't want to trace the schema load */
313 flags = ldb_get_flags(ldb);
314 ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
317 * setup the prefix mappings and schema info
319 ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res,
320 schema_dn, schema_attrs,
321 DSDB_FLAG_NEXT_MODULE, NULL);
322 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
323 ldb_reset_err_string(ldb);
324 ldb_debug(ldb, LDB_DEBUG_WARNING,
325 "schema_load_init: no schema head present: (skip schema loading)\n");
327 } else if (ret != LDB_SUCCESS) {
328 ldb_asprintf_errstring(ldb,
329 "dsdb_schema: failed to search the schema head: %s",
335 * load the attribute definitions
337 ret = dsdb_module_search(module, tmp_ctx, &res,
338 schema_dn, LDB_SCOPE_ONELEVEL, NULL,
339 DSDB_FLAG_NEXT_MODULE |
340 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
342 "(|(objectClass=attributeSchema)(objectClass=classSchema))");
343 if (ret != LDB_SUCCESS) {
344 ldb_asprintf_errstring(ldb,
345 "dsdb_schema: failed to search attributeSchema and classSchema objects: %s",
350 ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
351 schema_res, res, schema, &error_string);
352 if (ret != LDB_SUCCESS) {
353 ldb_asprintf_errstring(ldb,
354 "dsdb_schema load failed: %s",
359 (*schema)->refresh_in_progress = true;
361 /* If we have the readOnlySchema opaque, then don't check for
362 * runtime schema updates, as they are not permitted (we would
363 * have to update the backend server schema too */
364 if (!ldb_get_opaque(ldb, "readOnlySchema")) {
365 (*schema)->refresh_fn = dsdb_schema_refresh;
366 (*schema)->loaded_from_module = module;
367 (*schema)->loaded_usn = current_usn;
370 /* "dsdb_set_schema()" steals schema into the ldb_context */
371 ret = dsdb_set_schema(ldb, (*schema));
373 (*schema)->refresh_in_progress = false;
374 (*schema)->last_refresh = time(NULL);
376 if (ret != LDB_SUCCESS) {
377 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
378 "schema_load_init: dsdb_set_schema() failed: %d:%s: %s",
379 ret, ldb_strerror(ret), ldb_errstring(ldb));
383 /* Ensure this module won't go away before the callback */
384 if (talloc_reference(*schema, ldb) == NULL) {
386 ret = LDB_ERR_OPERATIONS_ERROR;
390 if (flags & LDB_FLG_ENABLE_TRACING) {
391 flags = ldb_get_flags(ldb);
392 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
394 talloc_free(tmp_ctx);
399 static int schema_load_init(struct ldb_module *module)
401 struct schema_load_private_data *private_data;
402 struct dsdb_schema *schema;
403 struct ldb_context *ldb = ldb_module_get_ctx(module);
405 uint64_t current_usn;
406 struct ldb_dn *schema_dn;
408 private_data = talloc_zero(module, struct schema_load_private_data);
409 if (private_data == NULL) {
413 ldb_module_set_private(module, private_data);
415 ret = ldb_next_init(module);
416 if (ret != LDB_SUCCESS) {
420 if (dsdb_get_schema(ldb, NULL)) {
424 schema_dn = ldb_get_schema_basedn(ldb);
426 ldb_reset_err_string(ldb);
427 ldb_debug(ldb, LDB_DEBUG_WARNING,
428 "schema_load_init: no schema dn present: (skip schema loading)\n");
432 ret = dsdb_module_load_partition_usn(module, schema_dn, ¤t_usn, NULL, NULL);
433 if (ret != LDB_SUCCESS) {
434 /* Ignore the error and just reload the DB more often */
438 ret = dsdb_schema_from_db(module, schema_dn, current_usn, &schema);
439 /* We don't care too much on the result of this action
440 * the most probable reason for this to fail is that the tdb didn't
441 * exists yet and this will be corrected by the partition module.
443 if (ret == LDB_SUCCESS && schema_metadata_open(module) == LDB_SUCCESS) {
446 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
447 if (ret == LDB_SUCCESS) {
448 schema->metadata_usn = value;
450 schema->metadata_usn = 0;
456 static int schema_search(struct ldb_module *module, struct ldb_request *req)
458 struct dsdb_schema *schema;
459 struct ldb_context *ldb = ldb_module_get_ctx(module);
462 struct schema_load_private_data *private_data =
463 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
465 schema = dsdb_get_schema(ldb, NULL);
466 if (schema && private_data && !private_data->in_transaction) {
467 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
468 if (ret == LDB_SUCCESS && schema->metadata_usn < value) {
469 /* The usn of the schema was changed in the metadata,
470 * this indicate that another process has modified the schema and
471 * that a reload is needed.
473 schema->last_refresh = 0;
474 schema = dsdb_get_schema(ldb, NULL);
478 return ldb_next_request(module, req);
481 static int schema_load_start_transaction(struct ldb_module *module)
483 struct schema_load_private_data *private_data =
484 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
485 struct dsdb_schema *schema;
486 struct ldb_context *ldb = ldb_module_get_ctx(module);
490 schema = dsdb_get_schema(ldb, NULL);
491 if (!private_data->metadata) {
492 schema_metadata_open(module);
494 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
495 if (ret == LDB_SUCCESS && schema->metadata_usn < value) {
496 /* The usn of the schema was changed in the metadata,
497 * this indicate that another process has modified the schema and
498 * that a reload is needed.
500 schema->last_refresh = 0;
501 schema = dsdb_get_schema(ldb, NULL);
503 private_data->in_transaction = true;
505 return ldb_next_start_trans(module);
508 static int schema_load_end_transaction(struct ldb_module *module)
510 struct schema_load_private_data *private_data =
511 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
513 private_data->in_transaction = false;
515 return ldb_next_end_trans(module);
518 static int schema_load_del_transaction(struct ldb_module *module)
520 struct schema_load_private_data *private_data =
521 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
523 private_data->in_transaction = false;
525 return ldb_next_del_trans(module);
528 static int schema_load_extended(struct ldb_module *module, struct ldb_request *req)
531 struct ldb_context *ldb = ldb_module_get_ctx(module);
532 struct dsdb_schema *schema;
534 if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) {
535 return ldb_next_request(module, req);
537 lastts = (time_t *)ldb_get_opaque(ldb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME);
539 lastts = talloc(ldb, time_t);
541 schema = dsdb_get_schema(ldb, NULL);
542 /* Force a refresh */
543 schema->last_refresh = 0;
545 ldb_set_opaque(ldb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME, lastts);
547 /* Pass to next module, the partition one should finish the chain */
548 return ldb_next_request(module, req);
552 static const struct ldb_module_ops ldb_schema_load_module_ops = {
553 .name = "schema_load",
554 .init_context = schema_load_init,
555 .extended = schema_load_extended,
556 .search = schema_search,
557 .start_transaction = schema_load_start_transaction,
558 .end_transaction = schema_load_end_transaction,
559 .del_transaction = schema_load_del_transaction,
562 int ldb_schema_load_module_init(const char *version)
564 LDB_MODULE_CHECK_VERSION(version);
565 return ldb_register_module(&ldb_schema_load_module_ops);