cfd88fec467f35df2253ac12be4177019a54544a
[metze/samba/wip.git] / source4 / dsdb / samdb / ldb_modules / schema_load.c
1 /* 
2    Unix SMB/CIFS mplementation.
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
36 #include "system/filesys.h"
37 struct schema_load_private_data {
38         struct ldb_module *module;
39         uint64_t in_transaction;
40         uint64_t in_read_transaction;
41         struct tdb_wrap *metadata;
42         uint64_t schema_seq_num_cache;
43         int tdb_seqnum;
44
45         /*
46          * Please write out the updated schema on the next transaction
47          * start
48          */
49         bool need_write;
50 };
51
52 static int dsdb_schema_from_db(struct ldb_module *module,
53                                TALLOC_CTX *mem_ctx,
54                                uint64_t schema_seq_num,
55                                struct dsdb_schema **schema);
56
57 /*
58  * Open sam.ldb.d/metadata.tdb.
59  */
60 static int schema_metadata_open(struct ldb_module *module)
61 {
62         struct schema_load_private_data *data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
63         struct ldb_context *ldb = ldb_module_get_ctx(module);
64         TALLOC_CTX *tmp_ctx;
65         struct loadparm_context *lp_ctx;
66         const char *sam_name;
67         char *filename;
68         int open_flags;
69         struct stat statbuf;
70
71         if (!data) {
72                 return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
73                                         "schema_load: metadata not initialized");
74         }
75         data->metadata = NULL;
76
77         tmp_ctx = talloc_new(NULL);
78         if (tmp_ctx == NULL) {
79                 return ldb_module_oom(module);
80         }
81
82         sam_name = (const char *)ldb_get_opaque(ldb, "ldb_url");
83         if (!sam_name) {
84                 talloc_free(tmp_ctx);
85                 return ldb_operr(ldb);
86         }
87         if (strncmp("tdb://", sam_name, 6) == 0) {
88                 sam_name += 6;
89         }
90         filename = talloc_asprintf(tmp_ctx, "%s.d/metadata.tdb", sam_name);
91         if (!filename) {
92                 talloc_free(tmp_ctx);
93                 return ldb_oom(ldb);
94         }
95
96         open_flags = O_RDWR;
97         if (stat(filename, &statbuf) != 0) {
98                 talloc_free(tmp_ctx);
99                 return LDB_ERR_OPERATIONS_ERROR;
100         }
101
102         lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
103                                        struct loadparm_context);
104
105         data->metadata = tdb_wrap_open(data, filename, 10,
106                                        lpcfg_tdb_flags(lp_ctx, TDB_DEFAULT|TDB_SEQNUM),
107                                        open_flags, 0660);
108         if (data->metadata == NULL) {
109                 talloc_free(tmp_ctx);
110                 return LDB_ERR_OPERATIONS_ERROR;
111         }
112
113         talloc_free(tmp_ctx);
114         return LDB_SUCCESS;
115 }
116
117 static int schema_metadata_get_uint64(struct schema_load_private_data *data,
118                                          const char *key, uint64_t *value,
119                                          uint64_t default_value)
120 {
121         struct tdb_context *tdb;
122         TDB_DATA tdb_key, tdb_data;
123         char *value_str;
124         TALLOC_CTX *tmp_ctx;
125         int tdb_seqnum;
126
127         if (!data) {
128                 *value = default_value;
129                 return LDB_SUCCESS;
130         }
131
132         if (!data->metadata) {
133                 return LDB_ERR_OPERATIONS_ERROR;
134         }
135
136         tdb_seqnum = tdb_get_seqnum(data->metadata->tdb);
137         if (tdb_seqnum == data->tdb_seqnum) {
138                 *value = data->schema_seq_num_cache;
139                 return LDB_SUCCESS;
140         }
141
142         tmp_ctx = talloc_new(NULL);
143         if (tmp_ctx == NULL) {
144                 return ldb_module_oom(data->module);
145         }
146
147         tdb = data->metadata->tdb;
148
149         tdb_key.dptr = (uint8_t *)discard_const_p(char, key);
150         tdb_key.dsize = strlen(key);
151
152         tdb_data = tdb_fetch(tdb, tdb_key);
153         if (!tdb_data.dptr) {
154                 if (tdb_error(tdb) == TDB_ERR_NOEXIST) {
155                         *value = default_value;
156                         talloc_free(tmp_ctx);
157                         return LDB_SUCCESS;
158                 } else {
159                         talloc_free(tmp_ctx);
160                         return ldb_module_error(data->module, LDB_ERR_OPERATIONS_ERROR,
161                                                 tdb_errorstr(tdb));
162                 }
163         }
164
165         value_str = talloc_strndup(tmp_ctx, (char *)tdb_data.dptr, tdb_data.dsize);
166         if (value_str == NULL) {
167                 SAFE_FREE(tdb_data.dptr);
168                 talloc_free(tmp_ctx);
169                 return ldb_module_oom(data->module);
170         }
171
172         /*
173          * Now store it in the cache.  We don't mind that tdb_seqnum
174          * may be stale now, that just means the cache won't be used
175          * next time
176          */
177         data->tdb_seqnum = tdb_seqnum;
178         data->schema_seq_num_cache = strtoull(value_str, NULL, 10);
179
180         *value = data->schema_seq_num_cache;
181
182         SAFE_FREE(tdb_data.dptr);
183         talloc_free(tmp_ctx);
184
185         return LDB_SUCCESS;
186 }
187
188 static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct tevent_context *ev,
189                                                struct dsdb_schema *schema, bool is_global_schema)
190 {
191         TALLOC_CTX *mem_ctx;
192         uint64_t schema_seq_num = 0;
193         int ret;
194         struct ldb_context *ldb = ldb_module_get_ctx(module);
195         struct dsdb_schema *new_schema;
196         
197         struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
198         if (!private_data) {
199                 /* We can't refresh until the init function has run */
200                 return schema;
201         }
202
203         if (schema != NULL) {
204                 /*
205                  * If we have a schema already (not in the startup)
206                  * and we are in a read or write transaction, then
207                  * avoid a schema reload, it can't have changed
208                  */
209                 if (private_data->in_transaction > 0
210                     || private_data->in_read_transaction > 0 ) {
211                         /*
212                          * If the refresh is not an expected part of a
213                          * larger transaction, then we don't allow a
214                          * schema reload during a transaction. This
215                          * stops others from modifying our schema
216                          * behind our backs
217                          */
218                         if (ldb_get_opaque(ldb,
219                                            "dsdb_schema_refresh_expected")
220                             != (void *)1) {
221                                 return schema;
222                         }
223                 }
224         }
225
226         SMB_ASSERT(ev == ldb_get_event_context(ldb));
227
228         mem_ctx = talloc_new(module);
229         if (mem_ctx == NULL) {
230                 return NULL;
231         }
232
233         /*
234          * We update right now the last refresh timestamp so that if
235          * the schema partition hasn't change we don't keep on retrying.
236          * Otherwise if the timestamp was update only when the schema has
237          * actually changed (and therefor completely reloaded) we would
238          * continue to hit the database to get the highest USN.
239          */
240
241         ret = schema_metadata_get_uint64(private_data,
242                                          DSDB_METADATA_SCHEMA_SEQ_NUM,
243                                          &schema_seq_num, 0);
244
245         if (schema != NULL) {
246                 if (ret == LDB_SUCCESS) {
247                         if (schema->metadata_usn == schema_seq_num) {
248                                 TALLOC_FREE(mem_ctx);
249                                 return schema;
250                         } else {
251                                 DEBUG(3, ("Schema refresh needed %lld != %lld\n",
252                                           (unsigned long long)schema->metadata_usn,
253                                           (unsigned long long)schema_seq_num));
254                         }
255                 } else {
256                         /* From an old provision it can happen that the tdb didn't exists yet */
257                         DEBUG(0, ("Error while searching for the schema usn in the metadata ignoring: %d:%s:%s\n",
258                               ret, ldb_strerror(ret), ldb_errstring(ldb)));
259                         TALLOC_FREE(mem_ctx);
260                         return schema;
261                 }
262         } else {
263                 DEBUG(10, ("Initial schema load needed, as we have no existing schema, seq_num: %lld\n",
264                           (unsigned long long)schema_seq_num));
265         }
266
267         ret = dsdb_schema_from_db(module, mem_ctx, schema_seq_num, &new_schema);
268         if (ret != LDB_SUCCESS) {
269                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
270                               "dsdb_schema_from_db() failed: %d:%s: %s",
271                               ret, ldb_strerror(ret), ldb_errstring(ldb));
272                 TALLOC_FREE(mem_ctx);
273                 return schema;
274         }
275
276         ret = dsdb_set_schema(ldb, new_schema, SCHEMA_MEMORY_ONLY);
277         if (ret != LDB_SUCCESS) {
278                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
279                               "dsdb_set_schema() failed: %d:%s: %s",
280                               ret, ldb_strerror(ret), ldb_errstring(ldb));
281                 TALLOC_FREE(mem_ctx);
282                 return schema;
283         }
284         if (is_global_schema) {
285                 dsdb_make_schema_global(ldb, new_schema);
286         }
287         TALLOC_FREE(mem_ctx);
288         return new_schema;
289 }
290
291
292 /*
293   Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
294 */
295
296 static int dsdb_schema_from_db(struct ldb_module *module,
297                                TALLOC_CTX *mem_ctx,
298                                uint64_t schema_seq_num,
299                                struct dsdb_schema **schema)
300 {
301         struct ldb_context *ldb = ldb_module_get_ctx(module);
302         TALLOC_CTX *tmp_ctx;
303         char *error_string;
304         int ret, i;
305         struct ldb_dn *schema_dn = ldb_get_schema_basedn(ldb);
306         struct ldb_result *res;
307         struct ldb_message *schema_msg = NULL;
308         static const char *schema_attrs[] = {
309                 DSDB_SCHEMA_COMMON_ATTRS,
310                 DSDB_SCHEMA_ATTR_ATTRS,
311                 DSDB_SCHEMA_CLASS_ATTRS,
312                 "prefixMap",
313                 "schemaInfo",
314                 "fSMORoleOwner",
315                 NULL
316         };
317         unsigned flags;
318
319         tmp_ctx = talloc_new(module);
320         if (!tmp_ctx) {
321                 return ldb_oom(ldb);
322         }
323
324         /* we don't want to trace the schema load */
325         flags = ldb_get_flags(ldb);
326         ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
327
328         /*
329          * Load the attribute and class definitions, as well as
330          * the schema object. We do this in one search and then
331          * split it so that there isn't a race condition when
332          * the schema is changed between two searches.
333          */
334         ret = dsdb_module_search(module, tmp_ctx, &res,
335                                  schema_dn, LDB_SCOPE_SUBTREE,
336                                  schema_attrs,
337                                  DSDB_FLAG_NEXT_MODULE |
338                                  DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
339                                  NULL,
340                                  "(|(objectClass=attributeSchema)"
341                                  "(objectClass=classSchema)"
342                                  "(objectClass=dMD))");
343         if (ret != LDB_SUCCESS) {
344                 ldb_asprintf_errstring(ldb, 
345                                        "dsdb_schema: failed to search attributeSchema and classSchema objects: %s",
346                                        ldb_errstring(ldb));
347                 goto failed;
348         }
349
350         /*
351          * Separate the schema object from the attribute and
352          * class objects.
353          */
354         for (i = 0; i < res->count; i++) {
355                 if (ldb_msg_find_element(res->msgs[i], "prefixMap")) {
356                         schema_msg = res->msgs[i];
357                         break;
358                 }
359         }
360
361         if (schema_msg == NULL) {
362                 ldb_asprintf_errstring(ldb,
363                                        "dsdb_schema load failed: failed to find prefixMap");
364                 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
365                 goto failed;
366         }
367
368         ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
369                                            schema_msg, res, schema, &error_string);
370         if (ret != LDB_SUCCESS) {
371                 ldb_asprintf_errstring(ldb, 
372                                        "dsdb_schema load failed: %s",
373                                        error_string);
374                 goto failed;
375         }
376
377         (*schema)->metadata_usn = schema_seq_num;
378
379         talloc_steal(mem_ctx, *schema);
380
381 failed:
382         if (flags & LDB_FLG_ENABLE_TRACING) {
383                 flags = ldb_get_flags(ldb);
384                 ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
385         }
386         talloc_free(tmp_ctx);
387         return ret;
388 }       
389
390 static int schema_load(struct ldb_context *ldb,
391                        struct ldb_module *module,
392                        bool *need_write)
393 {
394         struct dsdb_schema *schema;
395         void *readOnlySchema;
396         int ret, metadata_ret;
397         TALLOC_CTX *frame = talloc_stackframe();
398         
399         schema = dsdb_get_schema(ldb, frame);
400
401         metadata_ret = schema_metadata_open(module);
402
403         /* We might already have a schema */
404         if (schema != NULL) {
405                 /* If we have the metadata.tdb, then hook up the refresh function */
406                 if (metadata_ret == LDB_SUCCESS && dsdb_uses_global_schema(ldb)) {
407                         ret = dsdb_set_schema_refresh_function(ldb, dsdb_schema_refresh, module);
408
409                         if (ret != LDB_SUCCESS) {
410                                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
411                                               "schema_load_init: dsdb_set_schema_refresh_fns() failed: %d:%s: %s",
412                                               ret, ldb_strerror(ret), ldb_errstring(ldb));
413                                 TALLOC_FREE(frame);
414                                 return ret;
415                         }
416                 }
417
418                 TALLOC_FREE(frame);
419                 return LDB_SUCCESS;
420         }
421
422         readOnlySchema = ldb_get_opaque(ldb, "readOnlySchema");
423
424         /* If we have the readOnlySchema opaque, then don't check for
425          * runtime schema updates, as they are not permitted (we would
426          * have to update the backend server schema too */
427         if (readOnlySchema != NULL) {
428                 struct dsdb_schema *new_schema;
429                 ret = dsdb_schema_from_db(module, frame, 0, &new_schema);
430                 if (ret != LDB_SUCCESS) {
431                         ldb_debug_set(ldb, LDB_DEBUG_FATAL,
432                                       "schema_load_init: dsdb_schema_from_db() failed: %d:%s: %s",
433                                       ret, ldb_strerror(ret), ldb_errstring(ldb));
434                         TALLOC_FREE(frame);
435                         return ret;
436                 }
437
438                 /* "dsdb_set_schema()" steals schema into the ldb_context */
439                 ret = dsdb_set_schema(ldb, new_schema, SCHEMA_MEMORY_ONLY);
440                 if (ret != LDB_SUCCESS) {
441                         ldb_debug_set(ldb, LDB_DEBUG_FATAL,
442                                       "schema_load_init: dsdb_set_schema() failed: %d:%s: %s",
443                                       ret, ldb_strerror(ret), ldb_errstring(ldb));
444                         TALLOC_FREE(frame);
445                         return ret;
446                 }
447
448         } else if (metadata_ret == LDB_SUCCESS) {
449                 ret = dsdb_set_schema_refresh_function(ldb, dsdb_schema_refresh, module);
450
451                 if (ret != LDB_SUCCESS) {
452                         ldb_debug_set(ldb, LDB_DEBUG_FATAL,
453                                       "schema_load_init: dsdb_set_schema_refresh_fns() failed: %d:%s: %s",
454                                       ret, ldb_strerror(ret), ldb_errstring(ldb));
455                         TALLOC_FREE(frame);
456                         return ret;
457                 }
458         } else {
459                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
460                               "schema_load_init: failed to open metadata.tdb");
461                 TALLOC_FREE(frame);
462                 return metadata_ret;
463         }
464
465         schema = dsdb_get_schema(ldb, frame);
466
467         /* We do this, invoking the refresh handler, so we know that it works */
468         if (schema == NULL) {
469                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
470                               "schema_load_init: dsdb_get_schema failed");
471                 TALLOC_FREE(frame);
472                 return LDB_ERR_OPERATIONS_ERROR;
473         }
474
475         /* Now check the @INDEXLIST is correct, or fix it up */
476         ret = dsdb_schema_set_indices_and_attributes(ldb, schema,
477                                                      SCHEMA_COMPARE);
478         if (ret == LDB_ERR_BUSY) {
479                 *need_write = true;
480                 ret = LDB_SUCCESS;
481         } else {
482                 *need_write = false;
483         }
484
485         if (ret != LDB_SUCCESS) {
486                 ldb_asprintf_errstring(ldb, "Failed to update "
487                                        "@INDEXLIST and @ATTRIBUTES "
488                                        "records to match database schema: %s",
489                                        ldb_errstring(ldb));
490                 TALLOC_FREE(frame);
491                 return ret;
492         }
493
494         TALLOC_FREE(frame);
495         return LDB_SUCCESS;
496 }
497
498 static int schema_load_init(struct ldb_module *module)
499 {
500         struct ldb_context *ldb = ldb_module_get_ctx(module);
501         struct schema_load_private_data *private_data;
502         int ret;
503
504         private_data = talloc_zero(module, struct schema_load_private_data);
505         if (private_data == NULL) {
506                 return ldb_oom(ldb);
507         }
508         private_data->module = module;
509
510         ldb_module_set_private(module, private_data);
511
512         ret = ldb_next_init(module);
513         if (ret != LDB_SUCCESS) {
514                 return ret;
515         }
516
517         return schema_load(ldb, module, &private_data->need_write);
518 }
519
520 static int schema_load_start_transaction(struct ldb_module *module)
521 {
522         struct schema_load_private_data *private_data =
523                 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
524         struct ldb_context *ldb = ldb_module_get_ctx(module);
525         struct dsdb_schema *schema;
526         int ret;
527
528         ret = ldb_next_start_trans(module);
529         if (ret != LDB_SUCCESS) {
530                 return ret;
531         }
532
533         /* Try the schema refresh now */
534         schema = dsdb_get_schema(ldb, NULL);
535         if (schema == NULL) {
536                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
537                               "schema_load_init: dsdb_get_schema failed");
538                 return LDB_ERR_OPERATIONS_ERROR;
539         }
540
541         if (private_data->need_write) {
542                 ret = dsdb_schema_set_indices_and_attributes(ldb,
543                                                              schema,
544                                                              SCHEMA_WRITE);
545                 private_data->need_write = false;
546         }
547
548         private_data->in_transaction++;
549
550         return ret;
551 }
552
553 static int schema_load_end_transaction(struct ldb_module *module)
554 {
555         struct schema_load_private_data *private_data =
556                 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
557         struct ldb_context *ldb = ldb_module_get_ctx(module);
558
559         if (private_data->in_transaction == 0) {
560                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
561                               "schema_load_end_transaction: transaction mismatch");
562                 return LDB_ERR_OPERATIONS_ERROR;
563         }
564         private_data->in_transaction--;
565
566         return ldb_next_end_trans(module);
567 }
568
569 static int schema_load_del_transaction(struct ldb_module *module)
570 {
571         struct schema_load_private_data *private_data =
572                 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
573         struct ldb_context *ldb = ldb_module_get_ctx(module);
574
575         if (private_data->in_transaction == 0) {
576                 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
577                               "schema_load_del_transaction: transaction mismatch");
578                 return LDB_ERR_OPERATIONS_ERROR;
579         }
580         private_data->in_transaction--;
581
582         return ldb_next_del_trans(module);
583 }
584
585 /* This is called in a transaction held by the callers */
586 static int schema_load_extended(struct ldb_module *module, struct ldb_request *req)
587 {
588         struct ldb_context *ldb = ldb_module_get_ctx(module);
589         struct dsdb_schema *schema;
590         int ret;
591
592         if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) {
593                 return ldb_next_request(module, req);
594         }
595         /* Force a refresh */
596         schema = dsdb_get_schema(ldb, NULL);
597
598         ret = dsdb_schema_set_indices_and_attributes(ldb,
599                                                      schema,
600                                                      SCHEMA_WRITE);
601
602         if (ret != LDB_SUCCESS) {
603                 ldb_asprintf_errstring(ldb, "Failed to write new "
604                                        "@INDEXLIST and @ATTRIBUTES "
605                                        "records for updated schema: %s",
606                                        ldb_errstring(ldb));
607                 return ret;
608         }
609         
610         /* Pass to next module, the partition one should finish the chain */
611         return ldb_next_request(module, req);
612 }
613
614 static int schema_read_lock(struct ldb_module *module)
615 {
616         struct schema_load_private_data *private_data =
617                 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
618         int ret;
619
620         if (private_data == NULL) {
621                 return ldb_next_read_lock(module);
622         }
623
624         ret = ldb_next_read_lock(module);
625         if (ret != LDB_SUCCESS) {
626                 return ret;
627         }
628
629         if (private_data->in_transaction == 0 &&
630             private_data->in_read_transaction == 0) {
631                 /* Try the schema refresh now */
632                 dsdb_get_schema(ldb_module_get_ctx(module), NULL);
633         }
634
635         private_data->in_read_transaction++;
636
637         return LDB_SUCCESS;
638 }
639
640 static int schema_read_unlock(struct ldb_module *module)
641 {
642         struct schema_load_private_data *private_data =
643                 talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
644
645         if (private_data == NULL) {
646                 return ldb_next_read_unlock(module);
647         }
648
649         private_data->in_read_transaction--;
650
651         return ldb_next_read_unlock(module);
652 }
653
654
655 static const struct ldb_module_ops ldb_schema_load_module_ops = {
656         .name           = "schema_load",
657         .init_context   = schema_load_init,
658         .extended       = schema_load_extended,
659         .start_transaction = schema_load_start_transaction,
660         .end_transaction   = schema_load_end_transaction,
661         .del_transaction   = schema_load_del_transaction,
662         .read_lock      = schema_read_lock,
663         .read_unlock    = schema_read_unlock,
664 };
665
666 int ldb_schema_load_module_init(const char *version)
667 {
668         LDB_MODULE_CHECK_VERSION(version);
669         return ldb_register_module(&ldb_schema_load_module_ops);
670 }