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 : }
|