r4759: use ldb_attr_cmp() to compare attribute names
[ambi/samba-autobuild/.git] / source4 / lib / ldb / modules / schema.c
1 /* 
2    ldb database library
3
4    Copyright (C) Simo Sorce  2004
5
6      ** NOTE! The following LGPL license applies to the ldb
7      ** library. This does NOT imply that all of Samba is released
8      ** under the LGPL
9    
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 2 of the License, or (at your option) any later version.
14
15    This library 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 GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25 /*
26  *  Name: ldb
27  *
28  *  Component: ldb schema module
29  *
30  *  Description: add schema check functionality
31  *
32  *  Author: Simo Sorce
33  */
34
35 #include "includes.h"
36 #include "ldb/include/ldb.h"
37 #include "ldb/include/ldb_private.h"
38
39 struct attribute_syntax {
40         const char *name;
41         const char *syntax_id;
42 };
43
44 static struct attribute_syntax attrsyn[] = {
45                 { "Object(DS-DN)", "2.5.5.1"},
46                 { "String(Object-Identifier)", "2.5.5.2"},
47                 { "", "2.5.5.3"},
48                 { "String(Teletex)", "2.5.5.4"},
49                 { "String(IA5)", "2.5.5.5"}, /* Also String(Printable) */
50                 { "String(Numeric)", "2.5.5.6"},
51                 { "Object(DN-Binary)", "2.5.5.7"}, /* Also Object(OR-Name) */
52                 { "Boolean", "2.5.5.8"},
53                 { "Integer", "2.5.5.9"}, /* Also Enumeration (3 types ?) ... */
54                 { "String(Octet)", "2.5.5.10"}, /* Also Object(Replica-Link) */
55                 { "String(UTC-Time)", "2.5.5.11"}, /* Also String(Generalized-Time) */
56                 { "String(Unicode)", "2.5.5.12"},
57                 { "Object(Presentation-Address)", "2.5.5.13"},
58                 { "Object(DN-String)", "2.5.5.14"}, /* Also Object(Access-Point) */
59                 { "String(NT-Sec-Desc))", "2.5.5.15"},
60                 { "LargeInteger", "2.5.5.16"}, /* Also Interval ... */
61                 { "String(Sid)", "2.5.5.17"}
62         };
63
64 #define SCHEMA_TALLOC_CHECK(root, mem, ret) do { if (!mem) { talloc_free(root); return ret;} } while(0);
65
66 #define SCHEMA_FLAG_RESET       0
67 #define SCHEMA_FLAG_MOD_MASK    0x03
68 #define SCHEMA_FLAG_MOD_ADD     0x01
69 #define SCHEMA_FLAG_MOD_REPLACE 0x02
70 #define SCHEMA_FLAG_MOD_DELETE  0x03
71 #define SCHEMA_FLAG_AUXCLASS    0x10
72 #define SCHEMA_FLAG_CHECKED     0x20
73
74
75 struct private_data {
76         struct ldb_context *schema_db;
77         const char *error_string;
78 };
79
80 /* close */
81 static int schema_close(struct ldb_module *module)
82 {
83         return ldb_next_close(module);
84 }
85
86 /* search */
87 static int schema_search(struct ldb_module *module, const char *base,
88                        enum ldb_scope scope, const char *expression,
89                        const char * const *attrs, struct ldb_message ***res)
90 {
91         return ldb_next_search(module, base, scope, expression, attrs, res); 
92 }
93
94 /* search_free */
95 static int schema_search_free(struct ldb_module *module, struct ldb_message **res)
96 {
97         return ldb_next_search_free(module, res);
98 }
99
100 struct attribute_list {
101         int flags;
102         char *name;
103 };
104
105 struct schema_structures {
106         struct attribute_list *check_list;
107         struct attribute_list *objectclass_list;
108         struct attribute_list *must;
109         struct attribute_list *may;
110         int check_list_num;
111         int objectclass_list_num;
112         int must_num;
113         int may_num;
114 };
115
116 static int get_object_objectclasses(struct ldb_context *ldb, const char *dn, struct schema_structures *schema_struct)
117 {
118         char *filter = talloc_asprintf(schema_struct, "dn=%s", dn);
119         const char *attrs[] = {"objectClass", NULL};
120         struct ldb_message **srch;
121         int i, j, ret;
122
123         schema_struct->objectclass_list = NULL;
124         schema_struct->objectclass_list_num = 0;
125         ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, filter, attrs, &srch);
126         if (ret == 1) {
127                 for (i = 0; i < (*srch)->num_elements; i++) {
128                         schema_struct->objectclass_list_num = (*srch)->elements[i].num_values;
129                         schema_struct->objectclass_list = talloc_array(schema_struct,
130                                                                          struct attribute_list,
131                                                                          schema_struct->objectclass_list_num);
132                         if (schema_struct->objectclass_list == 0) {
133                                 ldb_search_free(ldb, srch);
134                                 return -1;
135                         }
136                         for (j = 0; j < schema_struct->objectclass_list_num; j++) {
137                                 schema_struct->objectclass_list[j].name = talloc_strndup(schema_struct->objectclass_list,
138                                                                                          (*srch)->elements[i].values[j].data,
139                                                                                          (*srch)->elements[i].values[j].length);
140                                 if (schema_struct->objectclass_list[j].name == 0) {
141                                         ldb_search_free(ldb, srch);
142                                         return -1;
143                                 }
144                                 schema_struct->objectclass_list[j].flags = SCHEMA_FLAG_RESET;
145                         }
146                 }
147                 ldb_search_free(ldb, srch);
148         } else {
149                 ldb_search_free(ldb, srch);
150                 return -1;
151         }
152
153         return 0;
154 }
155
156 static int get_check_list(struct ldb_module *module, struct schema_structures *schema_struct, const struct ldb_message *msg)
157 {
158         int i, j, k;
159
160         schema_struct->objectclass_list = NULL;
161         schema_struct->objectclass_list_num = 0;
162         schema_struct->check_list_num = msg->num_elements;
163         schema_struct->check_list = talloc_array(schema_struct,
164                                                    struct attribute_list,
165                                                    schema_struct->check_list_num);
166         if (schema_struct->check_list == 0) {
167                 return -1;
168         }
169         for (i = 0, j = 0; i < msg->num_elements; i++) {
170                 if (ldb_attr_cmp(msg->elements[i].name, "objectclass") == 0) {
171                         schema_struct->objectclass_list_num = msg->elements[i].num_values;
172                         schema_struct->objectclass_list = talloc_array(schema_struct,
173                                                                          struct attribute_list,
174                                                                          schema_struct->objectclass_list_num);
175                         if (schema_struct->objectclass_list == 0) {
176                                 return -1;
177                         }
178                         for (k = 0; k < schema_struct->objectclass_list_num; k++) {
179                                 schema_struct->objectclass_list[k].name = talloc_strndup(schema_struct->objectclass_list,
180                                                                                          msg->elements[i].values[k].data,
181                                                                                          msg->elements[i].values[k].length);
182                                 if (schema_struct->objectclass_list[k].name == 0) {
183                                         return -1;
184                                 }
185                                 schema_struct->objectclass_list[k].flags = msg->elements[i].flags;
186                         }
187                 }
188
189                 schema_struct->check_list[j].flags = msg->elements[i].flags;
190                 schema_struct->check_list[j].name = talloc_strdup(schema_struct->check_list,
191                                                                   msg->elements[i].name);
192                 if (schema_struct->check_list[j].name == 0) {
193                         return -1;
194                 }
195                 j++;
196         }
197
198         return 0;
199 }
200
201 static int add_attribute_uniq(struct attribute_list **list, int *list_num, int flags, struct ldb_message_element *el, void *mem_ctx)
202 {
203         int i, j, vals;
204
205         vals = el->num_values;
206         *list = talloc_realloc(mem_ctx, *list, struct attribute_list, *list_num + vals);
207         if (list == 0) {
208                 return -1;
209         }
210         for (i = 0, j = 0; i < vals; i++) {
211                 int c, found, len;
212
213                 found = 0;
214                 for (c = 0; c < *list_num; c++) {
215                         len = strlen((*list)[c].name);
216                         if (len == el->values[i].length) {
217                                 if (strncasecmp((*list)[c].name, el->values[i].data, len) == 0) {
218                                         found = 1;
219                                         break;
220                                 }
221                         }
222                 }
223                 if (!found) {
224                         (*list)[j + *list_num].name = talloc_strndup(*list, el->values[i].data, el->values[i].length);
225                         if ((*list)[j + *list_num].name == 0) {
226                                 return -1;
227                         }
228                         (*list)[j + *list_num].flags = flags;
229                         j++;
230                 }
231         }
232         *list_num += j;
233
234         return 0;
235 }
236
237 static int get_attr_list_recursive(struct ldb_module *module, struct ldb_context *ldb, struct schema_structures *schema_struct)
238 {
239         struct private_data *data = (struct private_data *)module->private_data;
240         struct ldb_message **srch;
241         int i, j;
242         int ret;
243
244         schema_struct->must = NULL;
245         schema_struct->may = NULL;
246         schema_struct->must_num = 0;
247         schema_struct->may_num = 0;
248         for (i = 0; i < schema_struct->objectclass_list_num; i++) {
249                 char *filter;
250
251                 if ((schema_struct->objectclass_list[i].flags & SCHEMA_FLAG_MOD_MASK) == SCHEMA_FLAG_MOD_DELETE) {
252                         continue;
253                 }
254                 filter = talloc_asprintf(schema_struct, "lDAPDisplayName=%s", schema_struct->objectclass_list[i].name);
255                 SCHEMA_TALLOC_CHECK(schema_struct, filter, -1);
256                 ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &srch);
257                 if (ret == 0) {
258                         int ok;
259
260                         ok = 0;
261                         /* suppose auxiliary classeschema_struct are not required */
262                         if (schema_struct->objectclass_list[i].flags & SCHEMA_FLAG_AUXCLASS) {
263                                 int d;
264                                 ok = 1;
265                                 schema_struct->objectclass_list_num -= 1;
266                                 for (d = i; d < schema_struct->objectclass_list_num; d++) {
267                                         schema_struct->objectclass_list[d] = schema_struct->objectclass_list[d + 1];
268                                 }
269                                 i -= 1;
270                         }
271                         if (!ok) {
272                                 /* Schema Violation: Object Class Description Not Found */
273                                 data->error_string = "ObjectClass not found";
274                                 return -1;
275                         }
276                         continue;
277                 } else {
278                         if (ret < 0) {
279                                 /* Schema DB Error: Error occurred retrieving Object Class Description */
280                                 data->error_string = "Internal error. Error retrieving schema objectclass";
281                                 return -1;
282                         }
283                         if (ret > 1) {
284                                 /* Schema DB Error: Too Many Records */
285                                 data->error_string = "Internal error. Too many records searching for schema objectclass";
286                                 return -1;
287                         }
288                 }
289
290                 /* Add inherited classes eliminating duplicates */
291                 /* fill in kust and may attribute lists */
292                 for (j = 0; j < (*srch)->num_elements; j++) {
293                         int is_aux, is_class;
294
295                         is_aux = 0;
296                         is_class = 0;
297                         if (ldb_attr_cmp((*srch)->elements[j].name, "systemAuxiliaryclass") == 0) {
298                                 is_aux = SCHEMA_FLAG_AUXCLASS;
299                                 is_class = 1;
300                         }
301                         if (ldb_attr_cmp((*srch)->elements[j].name, "subClassOf") == 0) {
302                                 is_class = 1;
303                         }
304
305                         if (is_class) {
306                                 if (add_attribute_uniq(&schema_struct->objectclass_list,
307                                                         &schema_struct->objectclass_list_num,
308                                                         is_aux,
309                                                         &(*srch)->elements[j],
310                                                         schema_struct) != 0) {
311                                         return -1;
312                                 }
313                         } else {
314
315                                 if (ldb_attr_cmp((*srch)->elements[j].name, "mustContain") == 0 ||
316                                         ldb_attr_cmp((*srch)->elements[j].name, "SystemMustContain") == 0) {
317                                         if (add_attribute_uniq(&schema_struct->must,
318                                                                 &schema_struct->must_num,
319                                                                 SCHEMA_FLAG_RESET,
320                                                                 &(*srch)->elements[j],
321                                                                 schema_struct) != 0) {
322                                                 return -1;
323                                         }
324                                 }
325
326                                 if (ldb_attr_cmp((*srch)->elements[j].name, "mayContain") == 0 ||
327                                     ldb_attr_cmp((*srch)->elements[j].name, "SystemMayContain") == 0) {
328
329                                         if (add_attribute_uniq(&schema_struct->may,
330                                                                 &schema_struct->may_num,
331                                                                 SCHEMA_FLAG_RESET,
332                                                                 &(*srch)->elements[j],
333                                                                 schema_struct) != 0) {
334                                                 return -1;
335                                         }
336                                 }
337                         }
338                 }
339
340                 ldb_search_free(ldb, srch);
341         }
342
343         return 0;
344 }
345
346 /* add_record */
347 static int schema_add_record(struct ldb_module *module, const struct ldb_message *msg)
348 {
349         struct private_data *data = (struct private_data *)module->private_data;
350         struct schema_structures *entry_structs;
351         int i, j;
352         int ret;
353
354         /* First implementation:
355                 Build up a list of must and mays from each objectclass
356                 Check all the musts are there and all the other attributes are mays
357                 Throw an error in case a check fail
358                 Free all structures and commit the change
359         */
360
361         entry_structs = talloc(module, struct schema_structures);
362         if (!entry_structs) {
363                 return -1;
364         }
365
366         ret = get_check_list(module, entry_structs, msg);
367         if (ret != 0) {
368                 talloc_free(entry_structs);
369                 return ret;
370         }
371
372         /* find all other objectclasses recursively */
373         ret = get_attr_list_recursive(module, data->schema_db, entry_structs);
374         if (ret != 0) {
375                 talloc_free(entry_structs);
376                 return ret;
377         }
378
379         /* now check all musts are present */
380         for (i = 0; i < entry_structs->must_num; i++) {
381                 int found;
382
383                 found = 0;
384                 for (j = 0; j < entry_structs->check_list_num; j++) {
385                         if (ldb_attr_cmp(entry_structs->must[i].name, entry_structs->check_list[j].name) == 0) {
386                                 entry_structs->check_list[j].flags = SCHEMA_FLAG_CHECKED;
387                                 found = 1;
388                                 break;
389                         }
390                 }
391
392                 if ( ! found ) {
393                         /* TODO: set the error string */
394                         data->error_string = "Objectclass violation, a required attribute is mischema_structing";
395                         talloc_free(entry_structs);
396                         return -1;
397                 }
398         }
399
400         /* now check all others atribs are found in mays */
401         for (i = 0; i < entry_structs->check_list_num; i++) {
402
403                 if (entry_structs->check_list[i].flags != SCHEMA_FLAG_CHECKED) {
404                         int found;
405
406                         found = 0;
407                         for (j = 0; j < entry_structs->may_num; j++) {
408                                 if (ldb_attr_cmp(entry_structs->may[j].name, entry_structs->check_list[i].name) == 0) {
409                                         entry_structs->check_list[i].flags = SCHEMA_FLAG_CHECKED;
410                                         found = 1;
411                                         break;
412                                 }
413                         }
414
415                         if ( ! found ) {
416                                 data->error_string = "Objectclass violation, an invalid attribute name was found";
417                                 talloc_free(entry_structs);
418                                 return -1;
419                         }
420                 }
421         }
422
423         talloc_free(entry_structs);
424
425         return ldb_next_add_record(module, msg);
426 }
427
428 /* modify_record */
429 static int schema_modify_record(struct ldb_module *module, const struct ldb_message *msg)
430 {
431         struct private_data *data = (struct private_data *)module->private_data;
432         struct schema_structures *entry_structs, *modify_structs;
433         int i, j;
434         int ret;
435
436         /* First implementation:
437                 Retrieve the ldap entry and get the objectclasses,
438                 add msg contained objectclasses if any.
439                 Build up a list of must and mays from each objectclass
440                 Check all musts for the defined objectclass and it's specific
441                 inheritance are there.
442                 Check all other the attributes are mays or musts.
443                 Throw an error in case a check fail.
444                 Free all structures and commit the change.
445         */
446
447         /* allocate object structs */
448         entry_structs = talloc(module, struct schema_structures);
449         if (!entry_structs) {
450                 return -1;
451         }
452
453         /* allocate modification entry structs */
454         modify_structs = talloc(entry_structs, struct schema_structures);
455         if (!modify_structs) {
456                 talloc_free(entry_structs);
457                 return -1;
458         }
459
460         /* get list of values to modify */
461         ret = get_check_list(module, modify_structs, msg);
462         if (ret != 0) {
463                 talloc_free(entry_structs);
464                 return ret;
465         }
466
467         /* find all modify objectclasses recursively if any objectclass is being added */
468         ret = get_attr_list_recursive(module, data->schema_db, modify_structs);
469         if (ret != 0) {
470                 talloc_free(entry_structs);
471                 return ret;
472         }
473
474         /* now search for the original object objectclasses */
475         ret = get_object_objectclasses(module->ldb, msg->dn, entry_structs);
476         if (ret != 0) {
477                 talloc_free(entry_structs);
478                 return ret;
479         }
480
481         /* find all other objectclasses recursively */
482         ret = get_attr_list_recursive(module, data->schema_db, entry_structs);
483         if (ret != 0) {
484                 talloc_free(entry_structs);
485                 return ret;
486         }
487
488         /* now check all entries are present either as musts or mays of curent objectclasses */
489         /* do not return errors there may be attirbutes defined in new objectclasses */
490         /* just mark them as being proved valid attribs */
491         for (i = 0; i < modify_structs->check_list_num; i++) {
492                 int found;
493
494                 found = 0;
495                 for (j = 0; j < entry_structs->must_num; j++) {
496                         if (ldb_attr_cmp(entry_structs->must[j].name, modify_structs->check_list[i].name) == 0) {
497                                 if ((modify_structs->check_list[i].flags & SCHEMA_FLAG_MOD_MASK) == SCHEMA_FLAG_MOD_DELETE) {
498                                         data->error_string = "Objectclass violation: trying to delete a required attribute";
499                                         talloc_free(entry_structs);
500                                         return -1;
501                                 }
502                                 modify_structs->check_list[i].flags |= SCHEMA_FLAG_CHECKED;
503                                 found = 1;
504                                 break;
505                         }
506                 }
507                 if ( ! found) {
508                         for (j = 0; j < entry_structs->may_num; j++) {
509                                 if (ldb_attr_cmp(entry_structs->may[j].name, modify_structs->check_list[i].name) == 0) {
510                                         modify_structs->check_list[i].flags |= SCHEMA_FLAG_CHECKED;
511                                         break;
512                                 }
513                         }
514                 }
515         }
516
517         /* now check all new objectclasses musts are present */
518         for (i = 0; i < modify_structs->must_num; i++) {
519                 int found;
520
521                 found = 0;
522                 for (j = 0; j < modify_structs->check_list_num; j++) {
523                         if (ldb_attr_cmp(modify_structs->must[i].name, modify_structs->check_list[j].name) == 0) {
524                                 if ((modify_structs->check_list[i].flags & SCHEMA_FLAG_MOD_MASK) == SCHEMA_FLAG_MOD_DELETE) {
525                                         data->error_string = "Objectclass violation: trying to delete a required attribute";
526                                         talloc_free(entry_structs);
527                                         return -1;
528                                 }
529                                 modify_structs->check_list[j].flags |= SCHEMA_FLAG_CHECKED;
530                                 found = 1;
531                                 break;
532                         }
533                 }
534
535                 if ( ! found ) {
536                         /* TODO: set the error string */
537                         data->error_string = "Objectclass violation, a required attribute is missing";
538                         talloc_free(entry_structs);
539                         return -1;
540                 }
541         }
542
543         /* now check all others atribs are found in mays */
544         for (i = 0; i < modify_structs->check_list_num; i++) {
545
546                 if ((modify_structs->check_list[i].flags & SCHEMA_FLAG_CHECKED) == 0 &&
547                     (modify_structs->check_list[i].flags & SCHEMA_FLAG_MOD_MASK) != SCHEMA_FLAG_MOD_DELETE) {
548                         int found;
549
550                         found = 0;
551                         for (j = 0; j < modify_structs->may_num; j++) {
552                                 if (ldb_attr_cmp(modify_structs->may[j].name, modify_structs->check_list[i].name) == 0) {
553                                         modify_structs->check_list[i].flags |= SCHEMA_FLAG_CHECKED;
554                                         found = 1;
555                                         break;
556                                 }
557                         }
558
559                         if ( ! found ) {
560                                 data->error_string = "Objectclass violation, an invalid attribute name was found";
561                                 talloc_free(entry_structs);
562                                 return -1;
563                         }
564                 }
565         }
566
567         talloc_free(entry_structs);
568
569         return ldb_next_modify_record(module, msg);
570 }
571
572 /* delete_record */
573 static int schema_delete_record(struct ldb_module *module, const char *dn)
574 {
575 /*      struct private_data *data = (struct private_data *)module->private_data; */
576         return ldb_next_delete_record(module, dn);
577 }
578
579 /* rename_record */
580 static int schema_rename_record(struct ldb_module *module, const char *olddn, const char *newdn)
581 {
582         return ldb_next_rename_record(module, olddn, newdn);
583 }
584
585 static int schema_named_lock(struct ldb_module *module, const char *name) {
586         return ldb_next_named_lock(module, name);
587 }
588
589 static int schema_named_unlock(struct ldb_module *module, const char *name) {
590         return ldb_next_named_unlock(module, name);
591 }
592
593 /* return extended error information */
594 static const char *schema_errstring(struct ldb_module *module)
595 {
596         struct private_data *data = (struct private_data *)module->private_data;
597
598         if (data->error_string) {
599                 const char *error;
600
601                 error = data->error_string;
602                 data->error_string = NULL;
603                 return error;
604         }
605
606         return ldb_next_errstring(module);
607 }
608
609 static const struct ldb_module_ops schema_ops = {
610         "schema",
611         schema_close, 
612         schema_search,
613         schema_search_free,
614         schema_add_record,
615         schema_modify_record,
616         schema_delete_record,
617         schema_rename_record,
618         schema_named_lock,
619         schema_named_unlock,
620         schema_errstring,
621 };
622
623 #define SCHEMA_PREFIX           "schema:"
624 #define SCHEMA_PREFIX_LEN       7
625
626 #ifdef HAVE_DLOPEN_DISABLED
627 struct ldb_module *init_module(struct ldb_context *ldb, const char *options[])
628 #else
629 struct ldb_module *schema_module_init(struct ldb_context *ldb, const char *options[])
630 #endif
631 {
632         struct ldb_module *ctx;
633         struct private_data *data;
634         char *db_url = NULL;
635         int i;
636
637         ctx = talloc(ldb, struct ldb_module);
638         if (!ctx) {
639                 return NULL;
640         }
641
642         if (options) {
643                 for (i = 0; options[i] != NULL; i++) {
644                         if (strncmp(options[i], SCHEMA_PREFIX, SCHEMA_PREFIX_LEN) == 0) {
645                                 db_url = talloc_strdup(ctx, &options[i][SCHEMA_PREFIX_LEN]);
646                                 SCHEMA_TALLOC_CHECK(ctx, db_url, NULL);
647                         }
648                 }
649         }
650
651         if (!db_url) { /* search if it is defined in the calling ldb */
652                 int ret;
653                 const char * attrs[] = { "@SCHEMADB", NULL };
654                 struct ldb_message **msgs;
655
656                 ret = ldb_search(ldb, "", LDB_SCOPE_BASE, "dn=@MODULES", (const char * const *)attrs, &msgs);
657                 if (ret == 0) {
658                         ldb_debug(ldb, LDB_DEBUG_TRACE, "Schema DB not found\n");
659                         ldb_search_free(ldb, msgs);
660                         return NULL;
661                 } else {
662                         if (ret < 0) {
663                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for schema db, bailing out!\n", ldb_errstring(ldb));
664                                 ldb_search_free(ldb, msgs);
665                                 return NULL;
666                         }
667                         if (ret > 1) {
668                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found, bailing out\n");
669                                 ldb_search_free(ldb, msgs);
670                                 return NULL;
671                         }
672
673                         db_url = talloc_strndup(ctx, msgs[0]->elements[0].values[0].data, msgs[0]->elements[0].values[0].length);
674                         SCHEMA_TALLOC_CHECK(ctx, db_url, NULL);
675                 }
676
677                 ldb_search_free(ldb, msgs);
678         }
679
680         data = talloc(ctx, struct private_data);
681         SCHEMA_TALLOC_CHECK(ctx, data, NULL);
682
683         data->schema_db = ldb_connect(db_url, 0, NULL); 
684         SCHEMA_TALLOC_CHECK(ctx, data->schema_db, NULL);
685
686         data->error_string = NULL;
687         ctx->private_data = data;
688         ctx->ldb = ldb;
689         ctx->prev = ctx->next = NULL;
690         ctx->ops = &schema_ops;
691
692         return ctx;
693 }