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 180225 : static int schema_metadata_open(struct ldb_module *module)
63 : {
64 180225 : struct schema_load_private_data *data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
65 180225 : struct ldb_context *ldb = ldb_module_get_ctx(module);
66 5974 : TALLOC_CTX *tmp_ctx;
67 5974 : struct loadparm_context *lp_ctx;
68 5974 : char *filename;
69 5974 : int open_flags;
70 5974 : struct stat statbuf;
71 :
72 180225 : if (!data) {
73 0 : return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
74 : "schema_load: metadata not initialized");
75 : }
76 180225 : data->metadata = NULL;
77 :
78 180225 : tmp_ctx = talloc_new(NULL);
79 180225 : if (tmp_ctx == NULL) {
80 0 : return ldb_module_oom(module);
81 : }
82 :
83 180225 : filename = ldb_relative_path(ldb,
84 : tmp_ctx,
85 : "sam.ldb.d/metadata.tdb");
86 180225 : if (filename == NULL) {
87 0 : talloc_free(tmp_ctx);
88 0 : return ldb_module_oom(module);
89 : }
90 :
91 180225 : open_flags = O_RDWR;
92 180225 : if (stat(filename, &statbuf) != 0) {
93 0 : talloc_free(tmp_ctx);
94 0 : return LDB_ERR_OPERATIONS_ERROR;
95 : }
96 :
97 180225 : lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
98 : struct loadparm_context);
99 :
100 180225 : data->metadata = tdb_wrap_open(data, filename, 10,
101 : lpcfg_tdb_flags(lp_ctx, TDB_DEFAULT|TDB_SEQNUM),
102 : open_flags, 0660);
103 180225 : if (data->metadata == NULL) {
104 0 : talloc_free(tmp_ctx);
105 0 : return LDB_ERR_OPERATIONS_ERROR;
106 : }
107 :
108 180225 : talloc_free(tmp_ctx);
109 180225 : return LDB_SUCCESS;
110 : }
111 :
112 46139941 : 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 3971212 : struct tdb_context *tdb;
117 3971212 : TDB_DATA tdb_key, tdb_data;
118 3971212 : char *value_str;
119 3971212 : TALLOC_CTX *tmp_ctx;
120 3971212 : int tdb_seqnum;
121 46139941 : int error = 0;
122 :
123 46139941 : if (!data) {
124 0 : *value = default_value;
125 0 : return LDB_SUCCESS;
126 : }
127 :
128 46139941 : if (!data->metadata) {
129 0 : return LDB_ERR_OPERATIONS_ERROR;
130 : }
131 :
132 46139941 : tdb_seqnum = tdb_get_seqnum(data->metadata->tdb);
133 46139941 : if (tdb_seqnum == data->tdb_seqnum) {
134 41247510 : *value = data->schema_seq_num_cache;
135 41247510 : return LDB_SUCCESS;
136 : }
137 :
138 4892431 : tmp_ctx = talloc_new(NULL);
139 4892431 : if (tmp_ctx == NULL) {
140 0 : return ldb_module_oom(data->module);
141 : }
142 :
143 4892431 : tdb = data->metadata->tdb;
144 :
145 4892431 : tdb_key.dptr = (uint8_t *)discard_const_p(char, key);
146 4892431 : tdb_key.dsize = strlen(key);
147 :
148 4892431 : tdb_data = tdb_fetch(tdb, tdb_key);
149 4892431 : if (!tdb_data.dptr) {
150 4444345 : if (tdb_error(tdb) == TDB_ERR_NOEXIST) {
151 4444345 : *value = default_value;
152 4444345 : talloc_free(tmp_ctx);
153 4444345 : 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 448086 : value_str = talloc_strndup(tmp_ctx, (char *)tdb_data.dptr, tdb_data.dsize);
162 448086 : 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 448086 : data->tdb_seqnum = tdb_seqnum;
174 448086 : data->schema_seq_num_cache = smb_strtoull(value_str,
175 : NULL,
176 : 10,
177 : &error,
178 : SMB_STR_STANDARD);
179 448086 : 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 448086 : *value = data->schema_seq_num_cache;
186 :
187 448086 : SAFE_FREE(tdb_data.dptr);
188 448086 : talloc_free(tmp_ctx);
189 :
190 448086 : return LDB_SUCCESS;
191 : }
192 :
193 163134338 : 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 10776412 : TALLOC_CTX *mem_ctx;
197 163134338 : uint64_t schema_seq_num = 0;
198 10776412 : int ret;
199 163134338 : struct ldb_context *ldb = ldb_module_get_ctx(module);
200 10776412 : struct dsdb_schema *new_schema;
201 :
202 163134338 : struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
203 163134338 : if (!private_data) {
204 : /* We can't refresh until the init function has run */
205 0 : return schema;
206 : }
207 :
208 163134338 : 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 163124462 : if (private_data->in_transaction > 0
215 107271262 : || 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 117578451 : if (ldb_get_opaque(ldb,
224 : "dsdb_schema_refresh_expected")
225 : != (void *)1) {
226 110189197 : return schema;
227 : }
228 : }
229 : }
230 :
231 46139941 : SMB_ASSERT(ev == ldb_get_event_context(ldb));
232 :
233 46139941 : mem_ctx = talloc_new(module);
234 46139941 : 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 46139941 : ret = schema_metadata_get_uint64(private_data,
247 : DSDB_METADATA_SCHEMA_SEQ_NUM,
248 : &schema_seq_num, 0);
249 :
250 46139941 : if (schema != NULL) {
251 46130065 : if (ret == LDB_SUCCESS) {
252 46130065 : if (schema->metadata_usn == schema_seq_num) {
253 46112587 : TALLOC_FREE(mem_ctx);
254 46112587 : return schema;
255 : } else {
256 17478 : 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 9876 : 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 27354 : ret = dsdb_schema_from_db(module, mem_ctx, schema_seq_num, &new_schema);
273 27354 : 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 27354 : ret = dsdb_set_schema(ldb, new_schema, SCHEMA_MEMORY_ONLY);
282 27354 : 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 27354 : if (is_global_schema) {
290 19878 : dsdb_make_schema_global(ldb, new_schema);
291 : }
292 27354 : TALLOC_FREE(mem_ctx);
293 27354 : 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 27415 : 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 27415 : 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 27415 : struct ldb_dn *schema_dn = ldb_get_schema_basedn(ldb);
311 316 : struct ldb_result *res;
312 27415 : 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 27415 : tmp_ctx = talloc_new(module);
325 27415 : if (!tmp_ctx) {
326 0 : return ldb_oom(ldb);
327 : }
328 :
329 : /* we don't want to trace the schema load */
330 27415 : flags = ldb_get_flags(ldb);
331 27415 : 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 27415 : 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 27415 : 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 24380407 : for (i = 0; i < res->count; i++) {
360 24380407 : if (ldb_msg_find_element(res->msgs[i], "prefixMap")) {
361 27415 : schema_msg = res->msgs[i];
362 27415 : break;
363 : }
364 : }
365 :
366 27415 : 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 27415 : ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
374 : schema_msg, res, schema, &error_string);
375 27415 : 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 27415 : (*schema)->metadata_usn = schema_seq_num;
383 :
384 27415 : talloc_steal(mem_ctx, *schema);
385 :
386 27415 : failed:
387 27415 : 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 27415 : talloc_free(tmp_ctx);
392 27415 : return ret;
393 : }
394 :
395 180225 : static int schema_load(struct ldb_context *ldb,
396 : struct ldb_module *module,
397 : bool *need_write)
398 : {
399 5974 : struct dsdb_schema *schema;
400 5974 : int ret, metadata_ret;
401 180225 : TALLOC_CTX *frame = talloc_stackframe();
402 :
403 180225 : schema = dsdb_get_schema(ldb, frame);
404 :
405 180225 : metadata_ret = schema_metadata_open(module);
406 :
407 : /* We might already have a schema */
408 180225 : if (schema != NULL) {
409 : /* If we have the metadata.tdb, then hook up the refresh function */
410 172423 : if (metadata_ret == LDB_SUCCESS && dsdb_uses_global_schema(ldb)) {
411 172218 : ret = dsdb_set_schema_refresh_function(ldb, dsdb_schema_refresh, module);
412 :
413 172218 : 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 172423 : TALLOC_FREE(frame);
423 172423 : return LDB_SUCCESS;
424 : }
425 :
426 7802 : if (metadata_ret == LDB_SUCCESS) {
427 7802 : ret = dsdb_set_schema_refresh_function(ldb, dsdb_schema_refresh, module);
428 :
429 7802 : 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 7802 : schema = dsdb_get_schema(ldb, frame);
444 :
445 : /* We do this, invoking the refresh handler, so we know that it works */
446 7802 : 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 7802 : ret = dsdb_schema_set_indices_and_attributes(ldb, schema,
455 : SCHEMA_COMPARE);
456 7802 : if (ret == LDB_ERR_BUSY) {
457 40 : *need_write = true;
458 40 : ret = LDB_SUCCESS;
459 : } else {
460 7762 : *need_write = false;
461 : }
462 :
463 7802 : 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 7802 : TALLOC_FREE(frame);
473 7584 : return LDB_SUCCESS;
474 : }
475 :
476 180225 : static int schema_load_init(struct ldb_module *module)
477 : {
478 180225 : struct ldb_context *ldb = ldb_module_get_ctx(module);
479 5974 : struct schema_load_private_data *private_data =
480 180225 : talloc_get_type_abort(ldb_module_get_private(module),
481 : struct schema_load_private_data);
482 5974 : int ret;
483 :
484 180225 : ret = ldb_next_init(module);
485 180225 : if (ret != LDB_SUCCESS) {
486 0 : return ret;
487 : }
488 :
489 180225 : return schema_load(ldb, module, &private_data->need_write);
490 : }
491 :
492 348733 : static int schema_load_start_transaction(struct ldb_module *module)
493 : {
494 2157 : struct schema_load_private_data *private_data =
495 348733 : talloc_get_type_abort(ldb_module_get_private(module),
496 : struct schema_load_private_data);
497 348733 : struct ldb_context *ldb = ldb_module_get_ctx(module);
498 2157 : struct dsdb_schema *schema;
499 2157 : int ret;
500 :
501 348733 : ret = ldb_next_start_trans(module);
502 348733 : if (ret != LDB_SUCCESS) {
503 0 : return ret;
504 : }
505 :
506 : /* Try the schema refresh now */
507 348733 : schema = dsdb_get_schema(ldb, NULL);
508 348733 : 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 348733 : if (private_data->need_write) {
515 35 : ret = dsdb_schema_set_indices_and_attributes(ldb,
516 : schema,
517 : SCHEMA_WRITE);
518 35 : private_data->need_write = false;
519 : }
520 :
521 348733 : private_data->in_transaction++;
522 :
523 348733 : return ret;
524 : }
525 :
526 303796 : static int schema_load_end_transaction(struct ldb_module *module)
527 : {
528 2152 : struct schema_load_private_data *private_data =
529 303796 : talloc_get_type_abort(ldb_module_get_private(module),
530 : struct schema_load_private_data);
531 303796 : struct ldb_context *ldb = ldb_module_get_ctx(module);
532 :
533 303796 : 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 303796 : private_data->in_transaction--;
539 :
540 303796 : return ldb_next_end_trans(module);
541 : }
542 :
543 44935 : static int schema_load_del_transaction(struct ldb_module *module)
544 : {
545 4 : struct schema_load_private_data *private_data =
546 44935 : talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
547 44935 : struct ldb_context *ldb = ldb_module_get_ctx(module);
548 :
549 44935 : 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 44935 : private_data->in_transaction--;
555 :
556 44935 : return ldb_next_del_trans(module);
557 : }
558 :
559 : /* This is called in a transaction held by the callers */
560 1651836 : static int schema_load_extended(struct ldb_module *module, struct ldb_request *req)
561 : {
562 1651836 : struct ldb_context *ldb = ldb_module_get_ctx(module);
563 95806 : struct dsdb_schema *schema;
564 95806 : int ret;
565 :
566 1651836 : if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_LOAD) == 0) {
567 :
568 61 : ret = dsdb_schema_from_db(module, req, 0, &schema);
569 61 : if (ret == LDB_SUCCESS) {
570 61 : return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
571 : }
572 0 : return ret;
573 :
574 1651775 : } 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 1651014 : return ldb_next_request(module, req);
594 : }
595 : }
596 :
597 18651552 : static int schema_read_lock(struct ldb_module *module)
598 : {
599 1113852 : struct schema_load_private_data *private_data =
600 18651552 : talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
601 1113852 : int ret;
602 :
603 18651552 : if (private_data == NULL) {
604 180225 : private_data = talloc_zero(module, struct schema_load_private_data);
605 180225 : if (private_data == NULL) {
606 0 : return ldb_module_oom(module);
607 : }
608 :
609 180225 : private_data->module = module;
610 :
611 180225 : ldb_module_set_private(module, private_data);
612 : }
613 :
614 18651552 : ret = ldb_next_read_lock(module);
615 18651552 : if (ret != LDB_SUCCESS) {
616 0 : return ret;
617 : }
618 :
619 18651552 : if (private_data->in_transaction == 0 &&
620 11794450 : private_data->in_read_transaction == 0) {
621 : /* Try the schema refresh now */
622 9751439 : dsdb_get_schema(ldb_module_get_ctx(module), NULL);
623 : }
624 :
625 18651552 : private_data->in_read_transaction++;
626 :
627 18651552 : return LDB_SUCCESS;
628 : }
629 :
630 18651552 : static int schema_read_unlock(struct ldb_module *module)
631 : {
632 1113852 : struct schema_load_private_data *private_data =
633 18651552 : talloc_get_type_abort(ldb_module_get_private(module),
634 : struct schema_load_private_data);
635 :
636 18651552 : private_data->in_read_transaction--;
637 :
638 18651552 : 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 5834 : int ldb_schema_load_module_init(const char *version)
654 : {
655 5834 : LDB_MODULE_CHECK_VERSION(version);
656 5834 : return ldb_register_module(&ldb_schema_load_module_ops);
657 : }
|