s4:dsdb/subtree_delete: do the recursive delete AS_SYSTEM/TRUSTED (bug #7711)
[Samba/gebeck_regimport.git] / source4 / dsdb / samdb / ldb_modules / schema_load.c
blobfaaf3f2071c4af72f52f9a45bc16c1746ec44075
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, 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);
52 TALLOC_CTX *tmp_ctx;
53 struct loadparm_context *lp_ctx;
54 const char *sam_name;
55 char *filename;
56 int open_flags;
57 struct stat statbuf;
59 if (!data) {
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) {
72 sam_name += 6;
74 if (!sam_name) {
75 talloc_free(tmp_ctx);
76 return ldb_operr(ldb);
78 filename = talloc_asprintf(tmp_ctx, "%s.d/metadata.tdb", sam_name);
79 if (!filename) {
80 talloc_free(tmp_ctx);
81 return ldb_oom(ldb);
84 open_flags = O_RDWR;
85 if (stat(filename, &statbuf) != 0) {
86 talloc_free(tmp_ctx);
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,
95 lp_ctx);
96 if (data->metadata == NULL) {
97 talloc_free(tmp_ctx);
98 return LDB_ERR_OPERATIONS_ERROR;
101 talloc_free(tmp_ctx);
102 return LDB_SUCCESS;
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;
112 char *value_str;
113 TALLOC_CTX *tmp_ctx;
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;
134 talloc_free(tmp_ctx);
135 return LDB_SUCCESS;
136 } else {
137 talloc_free(tmp_ctx);
138 return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
139 tdb_errorstr_compat(tdb));
143 value_str = talloc_strndup(tmp_ctx, (char *)tdb_data.dptr, tdb_data.dsize);
144 if (value_str == NULL) {
145 SAFE_FREE(tdb_data.dptr);
146 talloc_free(tmp_ctx);
147 return ldb_module_oom(module);
150 *value = strtoull(value_str, NULL, 10);
152 SAFE_FREE(tdb_data.dptr);
153 talloc_free(tmp_ctx);
155 return LDB_SUCCESS;
158 static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct dsdb_schema *schema, bool is_global_schema)
160 uint64_t current_usn, value;
161 int ret;
162 struct ldb_context *ldb = ldb_module_get_ctx(module);
163 struct dsdb_schema *new_schema;
164 time_t ts, lastts;
166 struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
167 if (!private_data) {
168 /* We can't refresh until the init function has run */
169 return schema;
172 /* We don't allow a schema reload during a transaction - nobody else can modify our schema behind our backs */
173 if (private_data->in_transaction) {
174 return schema;
177 lastts = schema->last_refresh;
178 ts = time(NULL);
179 if (lastts > (ts - schema->refresh_interval)) {
180 DEBUG(11, ("Less than %d seconds since last reload, returning cached version ts = %d\n", (int)schema->refresh_interval, (int)lastts));
181 return schema;
185 * We update right now the last refresh timestamp so that if
186 * the schema partition hasn't change we don't keep on retrying.
187 * Otherwise if the timestamp was update only when the schema has
188 * actually changed (and therefor completely reloaded) we would
189 * continue to hit the database to get the highest USN.
192 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
193 if (ret == LDB_SUCCESS) {
194 schema->metadata_usn = value;
195 } else {
196 /* From an old provision it can happen that the tdb didn't exists yet */
197 DEBUG(0, ("Error while searching for the schema usn in the metadata\n"));
198 schema->metadata_usn = 0;
200 schema->last_refresh = ts;
202 ret = dsdb_module_load_partition_usn(module, schema->base_dn, &current_usn, NULL, NULL);
203 if (ret != LDB_SUCCESS || current_usn == schema->loaded_usn) {
204 return schema;
207 ret = dsdb_schema_from_db(module, schema->base_dn, current_usn, &new_schema);
208 if (ret != LDB_SUCCESS) {
209 return schema;
212 if (is_global_schema) {
213 dsdb_make_schema_global(ldb, new_schema);
215 return new_schema;
220 Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
223 static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_dn, uint64_t current_usn,
224 struct dsdb_schema **schema)
226 struct ldb_context *ldb = ldb_module_get_ctx(module);
227 TALLOC_CTX *tmp_ctx;
228 char *error_string;
229 int ret;
230 struct ldb_result *schema_res;
231 struct ldb_result *res;
232 static const char *schema_attrs[] = {
233 "prefixMap",
234 "schemaInfo",
235 "fSMORoleOwner",
236 NULL
238 unsigned flags;
240 tmp_ctx = talloc_new(module);
241 if (!tmp_ctx) {
242 return ldb_oom(ldb);
245 /* we don't want to trace the schema load */
246 flags = ldb_get_flags(ldb);
247 ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
250 * setup the prefix mappings and schema info
252 ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res,
253 schema_dn, schema_attrs,
254 DSDB_FLAG_NEXT_MODULE, NULL);
255 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
256 ldb_reset_err_string(ldb);
257 ldb_debug(ldb, LDB_DEBUG_WARNING,
258 "schema_load_init: no schema head present: (skip schema loading)\n");
259 goto failed;
260 } else if (ret != LDB_SUCCESS) {
261 ldb_asprintf_errstring(ldb,
262 "dsdb_schema: failed to search the schema head: %s",
263 ldb_errstring(ldb));
264 goto failed;
268 * load the attribute definitions
270 ret = dsdb_module_search(module, tmp_ctx, &res,
271 schema_dn, LDB_SCOPE_ONELEVEL, NULL,
272 DSDB_FLAG_NEXT_MODULE |
273 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
274 NULL,
275 "(|(objectClass=attributeSchema)(objectClass=classSchema))");
276 if (ret != LDB_SUCCESS) {
277 ldb_asprintf_errstring(ldb,
278 "dsdb_schema: failed to search attributeSchema and classSchema objects: %s",
279 ldb_errstring(ldb));
280 goto failed;
283 ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
284 schema_res, res, schema, &error_string);
285 if (ret != LDB_SUCCESS) {
286 ldb_asprintf_errstring(ldb,
287 "dsdb_schema load failed: %s",
288 error_string);
289 goto failed;
292 (*schema)->refresh_in_progress = true;
294 /* If we have the readOnlySchema opaque, then don't check for
295 * runtime schema updates, as they are not permitted (we would
296 * have to update the backend server schema too */
297 if (!ldb_get_opaque(ldb, "readOnlySchema")) {
298 (*schema)->refresh_fn = dsdb_schema_refresh;
299 (*schema)->loaded_from_module = module;
300 (*schema)->loaded_usn = current_usn;
303 /* "dsdb_set_schema()" steals schema into the ldb_context */
304 ret = dsdb_set_schema(ldb, (*schema));
306 (*schema)->refresh_in_progress = false;
307 (*schema)->last_refresh = time(NULL);
309 if (ret != LDB_SUCCESS) {
310 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
311 "schema_load_init: dsdb_set_schema() failed: %d:%s: %s",
312 ret, ldb_strerror(ret), ldb_errstring(ldb));
313 goto failed;
316 /* Ensure this module won't go away before the callback. This
317 * causes every schema to have the LDB that originally loaded
318 * the first schema as a talloc child. */
319 if (talloc_reference(*schema, ldb) == NULL) {
320 ldb_oom(ldb);
321 ret = LDB_ERR_OPERATIONS_ERROR;
324 failed:
325 if (flags & LDB_FLG_ENABLE_TRACING) {
326 flags = ldb_get_flags(ldb);
327 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
329 talloc_free(tmp_ctx);
330 return ret;
334 static int schema_load_init(struct ldb_module *module)
336 struct schema_load_private_data *private_data;
337 struct dsdb_schema *schema;
338 struct ldb_context *ldb = ldb_module_get_ctx(module);
339 int ret;
340 uint64_t current_usn;
341 struct ldb_dn *schema_dn;
343 private_data = talloc_zero(module, struct schema_load_private_data);
344 if (private_data == NULL) {
345 return ldb_oom(ldb);
348 ldb_module_set_private(module, private_data);
350 ret = ldb_next_init(module);
351 if (ret != LDB_SUCCESS) {
352 return ret;
355 if (dsdb_get_schema(ldb, NULL)) {
356 return LDB_SUCCESS;
359 schema_dn = ldb_get_schema_basedn(ldb);
360 if (!schema_dn) {
361 ldb_reset_err_string(ldb);
362 ldb_debug(ldb, LDB_DEBUG_WARNING,
363 "schema_load_init: no schema dn present: (skip schema loading)\n");
364 return LDB_SUCCESS;
367 ret = dsdb_module_load_partition_usn(module, schema_dn, &current_usn, NULL, NULL);
368 if (ret != LDB_SUCCESS) {
369 /* Ignore the error and just reload the DB more often */
370 current_usn = 0;
373 ret = dsdb_schema_from_db(module, schema_dn, current_usn, &schema);
374 /* We don't care too much on the result of this action
375 * the most probable reason for this to fail is that the tdb didn't
376 * exists yet and this will be corrected by the partition module.
378 if (ret == LDB_SUCCESS && schema_metadata_open(module) == LDB_SUCCESS) {
379 uint64_t value;
381 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
382 if (ret == LDB_SUCCESS) {
383 schema->metadata_usn = value;
384 } else {
385 schema->metadata_usn = 0;
388 return ret;
391 static int schema_search(struct ldb_module *module, struct ldb_request *req)
393 struct dsdb_schema *schema;
394 struct ldb_context *ldb = ldb_module_get_ctx(module);
395 uint64_t value;
396 int ret;
397 struct schema_load_private_data *private_data =
398 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
400 schema = dsdb_get_schema(ldb, NULL);
401 if (schema && private_data && !private_data->in_transaction) {
402 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
403 if (ret == LDB_SUCCESS && schema->metadata_usn < value) {
404 /* The usn of the schema was changed in the metadata,
405 * this indicate that another process has modified the schema and
406 * that a reload is needed.
408 schema->last_refresh = 0;
409 schema = dsdb_get_schema(ldb, NULL);
413 return ldb_next_request(module, req);
416 static int schema_load_start_transaction(struct ldb_module *module)
418 struct schema_load_private_data *private_data =
419 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
420 struct dsdb_schema *schema;
421 struct ldb_context *ldb = ldb_module_get_ctx(module);
422 uint64_t value;
423 int ret;
425 schema = dsdb_get_schema(ldb, NULL);
426 if (!private_data->metadata) {
427 schema_metadata_open(module);
429 ret = schema_metadata_get_uint64(module, DSDB_METADATA_SCHEMA_SEQ_NUM, &value, 0);
430 if (ret == LDB_SUCCESS && schema->metadata_usn < value) {
431 /* The usn of the schema was changed in the metadata,
432 * this indicate that another process has modified the schema and
433 * that a reload is needed.
435 schema->last_refresh = 0;
436 schema = dsdb_get_schema(ldb, NULL);
438 private_data->in_transaction = true;
440 return ldb_next_start_trans(module);
443 static int schema_load_end_transaction(struct ldb_module *module)
445 struct schema_load_private_data *private_data =
446 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
448 private_data->in_transaction = false;
450 return ldb_next_end_trans(module);
453 static int schema_load_del_transaction(struct ldb_module *module)
455 struct schema_load_private_data *private_data =
456 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
458 private_data->in_transaction = false;
460 return ldb_next_del_trans(module);
463 static int schema_load_extended(struct ldb_module *module, struct ldb_request *req)
465 time_t *lastts;
466 struct ldb_context *ldb = ldb_module_get_ctx(module);
467 struct dsdb_schema *schema;
469 if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) {
470 return ldb_next_request(module, req);
472 lastts = (time_t *)ldb_get_opaque(ldb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME);
473 if (!lastts) {
474 lastts = talloc(ldb, time_t);
476 schema = dsdb_get_schema(ldb, NULL);
477 /* Force a refresh */
478 schema->last_refresh = 0;
479 *lastts = 0;
480 ldb_set_opaque(ldb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME, lastts);
482 /* Pass to next module, the partition one should finish the chain */
483 return ldb_next_request(module, req);
487 static const struct ldb_module_ops ldb_schema_load_module_ops = {
488 .name = "schema_load",
489 .init_context = schema_load_init,
490 .extended = schema_load_extended,
491 .search = schema_search,
492 .start_transaction = schema_load_start_transaction,
493 .end_transaction = schema_load_end_transaction,
494 .del_transaction = schema_load_del_transaction,
497 int ldb_schema_load_module_init(const char *version)
499 LDB_MODULE_CHECK_VERSION(version);
500 return ldb_register_module(&ldb_schema_load_module_ops);