s4:dsdb/schema_load: make error message more verbose
[Samba.git] / source4 / dsdb / samdb / ldb_modules / schema_load.c
blob17c20338b81d287048633085f54cea5aaf31dff1
1 /*
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/>.
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 "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 {
38 bool in_transaction;
39 struct tdb_wrap *metadata;
42 static int dsdb_schema_from_db(struct ldb_module *module,
43 TALLOC_CTX *mem_ctx,
44 uint64_t current_usn,
45 uint64_t schema_seq_num,
46 struct dsdb_schema **schema);
49 * Open sam.ldb.d/metadata.tdb.
51 static int schema_metadata_open(struct ldb_module *module)
53 struct schema_load_private_data *data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
54 struct ldb_context *ldb = ldb_module_get_ctx(module);
55 TALLOC_CTX *tmp_ctx;
56 struct loadparm_context *lp_ctx;
57 const char *sam_name;
58 char *filename;
59 int open_flags;
60 struct stat statbuf;
62 if (!data) {
63 return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
64 "schema_load: metadata not initialized");
66 data->metadata = NULL;
68 tmp_ctx = talloc_new(NULL);
69 if (tmp_ctx == NULL) {
70 return ldb_module_oom(module);
73 sam_name = (const char *)ldb_get_opaque(ldb, "ldb_url");
74 if (!sam_name) {
75 talloc_free(tmp_ctx);
76 return ldb_operr(ldb);
78 if (strncmp("tdb://", sam_name, 6) == 0) {
79 sam_name += 6;
81 filename = talloc_asprintf(tmp_ctx, "%s.d/metadata.tdb", sam_name);
82 if (!filename) {
83 talloc_free(tmp_ctx);
84 return ldb_oom(ldb);
87 open_flags = O_RDWR;
88 if (stat(filename, &statbuf) != 0) {
89 talloc_free(tmp_ctx);
90 return LDB_ERR_OPERATIONS_ERROR;
93 lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
94 struct loadparm_context);
96 data->metadata = tdb_wrap_open(data, filename, 10,
97 TDB_DEFAULT, open_flags, 0660,
98 lp_ctx);
99 if (data->metadata == NULL) {
100 talloc_free(tmp_ctx);
101 return LDB_ERR_OPERATIONS_ERROR;
104 talloc_free(tmp_ctx);
105 return LDB_SUCCESS;
108 static int schema_metadata_get_uint64(struct ldb_module *module,
109 const char *key, uint64_t *value,
110 uint64_t default_value)
112 struct schema_load_private_data *data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
113 struct tdb_context *tdb;
114 TDB_DATA tdb_key, tdb_data;
115 char *value_str;
116 TALLOC_CTX *tmp_ctx;
118 if (!data || !data->metadata) {
119 *value = default_value;
120 return LDB_SUCCESS;
123 tmp_ctx = talloc_new(NULL);
124 if (tmp_ctx == NULL) {
125 return ldb_module_oom(module);
128 tdb = data->metadata->tdb;
130 tdb_key.dptr = (uint8_t *)discard_const_p(char, key);
131 tdb_key.dsize = strlen(key);
133 tdb_data = tdb_fetch_compat(tdb, tdb_key);
134 if (!tdb_data.dptr) {
135 if (tdb_error(tdb) == TDB_ERR_NOEXIST) {
136 *value = default_value;
137 talloc_free(tmp_ctx);
138 return LDB_SUCCESS;
139 } else {
140 talloc_free(tmp_ctx);
141 return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
142 tdb_errorstr_compat(tdb));
146 value_str = talloc_strndup(tmp_ctx, (char *)tdb_data.dptr, tdb_data.dsize);
147 if (value_str == NULL) {
148 SAFE_FREE(tdb_data.dptr);
149 talloc_free(tmp_ctx);
150 return ldb_module_oom(module);
153 *value = strtoull(value_str, NULL, 10);
155 SAFE_FREE(tdb_data.dptr);
156 talloc_free(tmp_ctx);
158 return LDB_SUCCESS;
161 static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct tevent_context *ev,
162 struct dsdb_schema *schema, bool is_global_schema)
164 TALLOC_CTX *mem_ctx;
165 uint64_t current_usn, schema_seq_num = 0;
166 int ret;
167 struct ldb_context *ldb = ldb_module_get_ctx(module);
168 struct dsdb_schema *new_schema;
169 struct ldb_dn *schema_dn = ldb_get_schema_basedn(ldb);
170 time_t ts, lastts;
172 struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
173 if (!private_data) {
174 /* We can't refresh until the init function has run */
175 return schema;
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) {
180 return schema;
183 SMB_ASSERT(ev == ldb_get_event_context(ldb));
185 mem_ctx = talloc_new(module);
186 if (mem_ctx == NULL) {
187 return NULL;
191 * We update right now the last refresh timestamp so that if
192 * the schema partition hasn't change we don't keep on retrying.
193 * Otherwise if the timestamp was update only when the schema has
194 * actually changed (and therefor completely reloaded) we would
195 * continue to hit the database to get the highest USN.
198 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &schema_seq_num, 0);
200 if (schema != NULL) {
201 lastts = schema->last_refresh;
202 ts = time(NULL);
203 if (lastts > (ts - schema->refresh_interval)) {
204 DEBUG(11, ("Less than %d seconds since last reload, "
205 "returning cached version ts = %d\n",
206 (int)schema->refresh_interval,
207 (int)lastts));
208 TALLOC_FREE(mem_ctx);
209 return schema;
212 if (ret == LDB_SUCCESS) {
213 schema->metadata_usn = schema_seq_num;
214 } else {
215 /* From an old provision it can happen that the tdb didn't exists yet */
216 DEBUG(0, ("Error while searching for the schema usn in the metadata ignoring: %d:%s:%s\n",
217 ret, ldb_strerror(ret), ldb_errstring(ldb)));
218 schema->metadata_usn = 0;
220 schema->last_refresh = ts;
224 ret = dsdb_module_load_partition_usn(module, schema_dn, &current_usn, NULL, NULL);
225 if (ret != LDB_SUCCESS || (schema && (current_usn == schema->loaded_usn))) {
226 TALLOC_FREE(mem_ctx);
227 return schema;
230 ret = dsdb_schema_from_db(module, mem_ctx, current_usn, schema_seq_num, &new_schema);
231 if (ret != LDB_SUCCESS) {
232 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
233 "dsdb_schema_from_db() failed: %d:%s: %s",
234 ret, ldb_strerror(ret), ldb_errstring(ldb));
235 TALLOC_FREE(mem_ctx);
236 return schema;
239 ret = dsdb_set_schema(ldb, new_schema);
240 if (ret != LDB_SUCCESS) {
241 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
242 "dsdb_set_schema() failed: %d:%s: %s",
243 ret, ldb_strerror(ret), ldb_errstring(ldb));
244 TALLOC_FREE(mem_ctx);
245 return schema;
247 if (is_global_schema) {
248 dsdb_make_schema_global(ldb, new_schema);
250 TALLOC_FREE(mem_ctx);
251 return new_schema;
256 Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
259 static int dsdb_schema_from_db(struct ldb_module *module,
260 TALLOC_CTX *mem_ctx,
261 uint64_t current_usn,
262 uint64_t schema_seq_num,
263 struct dsdb_schema **schema)
265 struct ldb_context *ldb = ldb_module_get_ctx(module);
266 TALLOC_CTX *tmp_ctx;
267 char *error_string;
268 int ret;
269 struct ldb_dn *schema_dn = ldb_get_schema_basedn(ldb);
270 struct ldb_result *schema_res;
271 struct ldb_result *res;
272 static const char *schema_attrs[] = {
273 "prefixMap",
274 "schemaInfo",
275 "fSMORoleOwner",
276 NULL
278 unsigned flags;
280 tmp_ctx = talloc_new(module);
281 if (!tmp_ctx) {
282 return ldb_oom(ldb);
285 /* we don't want to trace the schema load */
286 flags = ldb_get_flags(ldb);
287 ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
290 * setup the prefix mappings and schema info
292 ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res,
293 schema_dn, schema_attrs,
294 DSDB_FLAG_NEXT_MODULE, NULL);
295 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
296 ldb_reset_err_string(ldb);
297 ldb_debug(ldb, LDB_DEBUG_WARNING,
298 "schema_load_init: no schema head present: (skip schema loading)\n");
299 goto failed;
300 } else if (ret != LDB_SUCCESS) {
301 ldb_asprintf_errstring(ldb,
302 "dsdb_schema: failed to search the schema head: %s",
303 ldb_errstring(ldb));
304 goto failed;
308 * load the attribute definitions
310 ret = dsdb_module_search(module, tmp_ctx, &res,
311 schema_dn, LDB_SCOPE_ONELEVEL, NULL,
312 DSDB_FLAG_NEXT_MODULE |
313 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
314 NULL,
315 "(|(objectClass=attributeSchema)(objectClass=classSchema))");
316 if (ret != LDB_SUCCESS) {
317 ldb_asprintf_errstring(ldb,
318 "dsdb_schema: failed to search attributeSchema and classSchema objects: %s",
319 ldb_errstring(ldb));
320 goto failed;
323 ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
324 schema_res, res, schema, &error_string);
325 if (ret != LDB_SUCCESS) {
326 ldb_asprintf_errstring(ldb,
327 "dsdb_schema load failed: %s",
328 error_string);
329 goto failed;
332 (*schema)->loaded_usn = current_usn;
333 (*schema)->metadata_usn = schema_seq_num;
334 (*schema)->last_refresh = time(NULL);
336 talloc_steal(mem_ctx, *schema);
338 failed:
339 if (flags & LDB_FLG_ENABLE_TRACING) {
340 flags = ldb_get_flags(ldb);
341 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
343 talloc_free(tmp_ctx);
344 return ret;
348 static int schema_load_init(struct ldb_module *module)
350 struct schema_load_private_data *private_data;
351 struct ldb_context *ldb = ldb_module_get_ctx(module);
352 struct dsdb_schema *schema;
353 void *readOnlySchema;
354 int ret;
356 private_data = talloc_zero(module, struct schema_load_private_data);
357 if (private_data == NULL) {
358 return ldb_oom(ldb);
361 ldb_module_set_private(module, private_data);
363 ret = ldb_next_init(module);
364 if (ret != LDB_SUCCESS) {
365 return ret;
368 schema = dsdb_get_schema(ldb, NULL);
370 /* We might already have a schema */
371 if (schema != NULL) {
372 /* Hook up the refresh function */
373 if (dsdb_uses_global_schema(ldb)) {
374 ret = dsdb_set_schema_refresh_function(ldb, dsdb_schema_refresh, module);
376 if (ret != LDB_SUCCESS) {
377 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
378 "schema_load_init: dsdb_set_schema_refresh_fns() failed: %d:%s: %s",
379 ret, ldb_strerror(ret), ldb_errstring(ldb));
380 return ret;
384 return LDB_SUCCESS;
387 readOnlySchema = ldb_get_opaque(ldb, "readOnlySchema");
389 /* If we have the readOnlySchema opaque, then don't check for
390 * runtime schema updates, as they are not permitted (we would
391 * have to update the backend server schema too */
392 if (readOnlySchema != NULL) {
393 struct dsdb_schema *new_schema;
394 ret = dsdb_schema_from_db(module, private_data, 0, 0, &new_schema);
395 if (ret != LDB_SUCCESS) {
396 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
397 "schema_load_init: dsdb_schema_from_db() failed: %d:%s: %s",
398 ret, ldb_strerror(ret), ldb_errstring(ldb));
399 return ret;
402 /* "dsdb_set_schema()" steals schema into the ldb_context */
403 ret = dsdb_set_schema(ldb, new_schema);
404 if (ret != LDB_SUCCESS) {
405 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
406 "schema_load_init: dsdb_set_schema() failed: %d:%s: %s",
407 ret, ldb_strerror(ret), ldb_errstring(ldb));
408 return ret;
411 } else {
412 ret = dsdb_set_schema_refresh_function(ldb, dsdb_schema_refresh, module);
414 if (ret != LDB_SUCCESS) {
415 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
416 "schema_load_init: dsdb_set_schema_refresh_fns() failed: %d:%s: %s",
417 ret, ldb_strerror(ret), ldb_errstring(ldb));
418 return ret;
422 schema = dsdb_get_schema(ldb, NULL);
424 /* We do this, invoking the refresh handler, so we know that it works */
425 if (schema == NULL) {
426 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
427 "schema_load_init: dsdb_get_schema failed");
428 return LDB_ERR_OPERATIONS_ERROR;
431 return ret;
434 static int schema_search(struct ldb_module *module, struct ldb_request *req)
436 struct dsdb_schema *schema;
437 struct ldb_context *ldb = ldb_module_get_ctx(module);
438 uint64_t value;
439 int ret;
440 struct schema_load_private_data *private_data =
441 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
443 schema = dsdb_get_schema(ldb, NULL);
444 if (schema && private_data && !private_data->in_transaction) {
445 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
446 if (ret == LDB_SUCCESS && schema->metadata_usn < value) {
447 /* The usn of the schema was changed in the metadata,
448 * this indicate that another process has modified the schema and
449 * that a reload is needed.
451 schema->last_refresh = 0;
452 schema = dsdb_get_schema(ldb, NULL);
456 return ldb_next_request(module, req);
459 static int schema_load_start_transaction(struct ldb_module *module)
461 struct schema_load_private_data *private_data =
462 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
463 struct dsdb_schema *schema;
464 struct ldb_context *ldb = ldb_module_get_ctx(module);
465 uint64_t value;
466 int ret;
468 schema = dsdb_get_schema(ldb, NULL);
469 if (!private_data->metadata) {
470 schema_metadata_open(module);
472 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
473 if (ret == LDB_SUCCESS && schema->metadata_usn < value) {
474 /* The usn of the schema was changed in the metadata,
475 * this indicate that another process has modified the schema and
476 * that a reload is needed.
478 schema->last_refresh = 0;
479 schema = dsdb_get_schema(ldb, NULL);
481 private_data->in_transaction = true;
483 return ldb_next_start_trans(module);
486 static int schema_load_end_transaction(struct ldb_module *module)
488 struct schema_load_private_data *private_data =
489 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
491 private_data->in_transaction = false;
493 return ldb_next_end_trans(module);
496 static int schema_load_del_transaction(struct ldb_module *module)
498 struct schema_load_private_data *private_data =
499 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
501 private_data->in_transaction = false;
503 return ldb_next_del_trans(module);
506 static int schema_load_extended(struct ldb_module *module, struct ldb_request *req)
508 time_t *lastts;
509 struct ldb_context *ldb = ldb_module_get_ctx(module);
510 struct dsdb_schema *schema;
512 if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) {
513 return ldb_next_request(module, req);
515 lastts = (time_t *)ldb_get_opaque(ldb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME);
516 if (!lastts) {
517 lastts = talloc(ldb, time_t);
519 schema = dsdb_get_schema(ldb, NULL);
520 /* Force a refresh */
521 schema->last_refresh = 0;
522 *lastts = 0;
523 ldb_set_opaque(ldb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME, lastts);
525 /* Pass to next module, the partition one should finish the chain */
526 return ldb_next_request(module, req);
530 static const struct ldb_module_ops ldb_schema_load_module_ops = {
531 .name = "schema_load",
532 .init_context = schema_load_init,
533 .extended = schema_load_extended,
534 .search = schema_search,
535 .start_transaction = schema_load_start_transaction,
536 .end_transaction = schema_load_end_transaction,
537 .del_transaction = schema_load_del_transaction,
540 int ldb_schema_load_module_init(const char *version)
542 LDB_MODULE_CHECK_VERSION(version);
543 return ldb_register_module(&ldb_schema_load_module_ops);