Fix the mess with ldb includes.
[Samba/vl.git] / source4 / lib / ldb-samba / ldif_handlers.c
blobd92f21194651387be5f3869fdd8df2e8edd3b16f
1 /*
2 ldb database library - ldif handlers for Samba
4 Copyright (C) Andrew Tridgell 2005
5 Copyright (C) Andrew Bartlett 2006-2007
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
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 3 of the License, or (at your option) any later version.
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.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "ldb_private.h"
26 #include "dsdb/samdb/samdb.h"
27 #include "librpc/gen_ndr/ndr_security.h"
28 #include "librpc/gen_ndr/ndr_misc.h"
29 #include "librpc/gen_ndr/ndr_drsblobs.h"
30 #include "libcli/security/security.h"
31 #include "param/param.h"
34 convert a ldif formatted objectSid to a NDR formatted blob
36 static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx,
37 const struct ldb_val *in, struct ldb_val *out)
39 enum ndr_err_code ndr_err;
40 struct dom_sid *sid;
41 sid = dom_sid_parse_length(mem_ctx, in);
42 if (sid == NULL) {
43 return -1;
45 ndr_err = ndr_push_struct_blob(out, mem_ctx, NULL, sid,
46 (ndr_push_flags_fn_t)ndr_push_dom_sid);
47 talloc_free(sid);
48 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
49 return -1;
51 return 0;
55 convert a NDR formatted blob to a ldif formatted objectSid
57 static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
58 const struct ldb_val *in, struct ldb_val *out)
60 struct dom_sid *sid;
61 enum ndr_err_code ndr_err;
63 sid = talloc(mem_ctx, struct dom_sid);
64 if (sid == NULL) {
65 return -1;
67 ndr_err = ndr_pull_struct_blob_all(in, sid, NULL, sid,
68 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
69 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
70 talloc_free(sid);
71 return -1;
73 *out = data_blob_string_const(dom_sid_string(mem_ctx, sid));
74 talloc_free(sid);
75 if (out->data == NULL) {
76 return -1;
78 return 0;
81 static bool ldb_comparision_objectSid_isString(const struct ldb_val *v)
83 if (v->length < 3) {
84 return false;
87 if (strncmp("S-", (const char *)v->data, 2) != 0) return false;
89 return true;
93 compare two objectSids
95 static int ldb_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx,
96 const struct ldb_val *v1, const struct ldb_val *v2)
98 if (ldb_comparision_objectSid_isString(v1) && ldb_comparision_objectSid_isString(v2)) {
99 return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
100 } else if (ldb_comparision_objectSid_isString(v1)
101 && !ldb_comparision_objectSid_isString(v2)) {
102 struct ldb_val v;
103 int ret;
104 if (ldif_read_objectSid(ldb, mem_ctx, v1, &v) != 0) {
105 /* Perhaps not a string after all */
106 return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
108 ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2);
109 talloc_free(v.data);
110 return ret;
111 } else if (!ldb_comparision_objectSid_isString(v1)
112 && ldb_comparision_objectSid_isString(v2)) {
113 struct ldb_val v;
114 int ret;
115 if (ldif_read_objectSid(ldb, mem_ctx, v2, &v) != 0) {
116 /* Perhaps not a string after all */
117 return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
119 ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v);
120 talloc_free(v.data);
121 return ret;
123 return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
127 canonicalise a objectSid
129 static int ldb_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx,
130 const struct ldb_val *in, struct ldb_val *out)
132 if (ldb_comparision_objectSid_isString(in)) {
133 if (ldif_read_objectSid(ldb, mem_ctx, in, out) != 0) {
134 /* Perhaps not a string after all */
135 return ldb_handler_copy(ldb, mem_ctx, in, out);
137 return 0;
139 return ldb_handler_copy(ldb, mem_ctx, in, out);
142 static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx,
143 const struct ldb_val *in, struct ldb_val *out)
145 struct dom_sid sid;
146 enum ndr_err_code ndr_err;
147 if (ldb_comparision_objectSid_isString(in)) {
148 if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) {
149 return 0;
153 /* Perhaps not a string after all */
154 *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1);
156 if (!out->data) {
157 return -1;
160 (*out).length = strhex_to_str((char *)out->data, out->length,
161 (const char *)in->data, in->length);
163 /* Check it looks like a SID */
164 ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &sid,
165 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
166 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
167 return -1;
169 return 0;
173 convert a ldif formatted objectGUID to a NDR formatted blob
175 static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx,
176 const struct ldb_val *in, struct ldb_val *out)
178 struct GUID guid;
179 NTSTATUS status;
180 enum ndr_err_code ndr_err;
182 status = GUID_from_data_blob(in, &guid);
183 if (!NT_STATUS_IS_OK(status)) {
184 return -1;
187 ndr_err = ndr_push_struct_blob(out, mem_ctx, NULL, &guid,
188 (ndr_push_flags_fn_t)ndr_push_GUID);
189 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
190 return -1;
192 return 0;
196 convert a NDR formatted blob to a ldif formatted objectGUID
198 static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx,
199 const struct ldb_val *in, struct ldb_val *out)
201 struct GUID guid;
202 enum ndr_err_code ndr_err;
203 ndr_err = ndr_pull_struct_blob_all(in, mem_ctx, NULL, &guid,
204 (ndr_pull_flags_fn_t)ndr_pull_GUID);
205 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
206 return -1;
208 out->data = (uint8_t *)GUID_string(mem_ctx, &guid);
209 if (out->data == NULL) {
210 return -1;
212 out->length = strlen((const char *)out->data);
213 return 0;
216 static bool ldb_comparision_objectGUID_isString(const struct ldb_val *v)
218 if (v->length != 36 && v->length != 38) return false;
220 /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */
221 return true;
224 static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx,
225 const struct ldb_val *in, struct ldb_val *out)
227 struct GUID guid;
228 enum ndr_err_code ndr_err;
229 if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) {
230 return 0;
233 /* Try as 'hex' form */
234 if (in->length != 32) {
235 return -1;
238 *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1);
240 if (!out->data) {
241 return -1;
244 (*out).length = strhex_to_str((char *)out->data, out->length,
245 (const char *)in->data, in->length);
247 /* Check it looks like a GUID */
248 ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &guid,
249 (ndr_pull_flags_fn_t)ndr_pull_GUID);
250 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
251 return -1;
253 return 0;
257 compare two objectGUIDs
259 static int ldb_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx,
260 const struct ldb_val *v1, const struct ldb_val *v2)
262 if (ldb_comparision_objectGUID_isString(v1) && ldb_comparision_objectGUID_isString(v2)) {
263 return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
264 } else if (ldb_comparision_objectGUID_isString(v1)
265 && !ldb_comparision_objectGUID_isString(v2)) {
266 struct ldb_val v;
267 int ret;
268 if (ldif_read_objectGUID(ldb, mem_ctx, v1, &v) != 0) {
269 /* Perhaps it wasn't a valid string after all */
270 return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
272 ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2);
273 talloc_free(v.data);
274 return ret;
275 } else if (!ldb_comparision_objectGUID_isString(v1)
276 && ldb_comparision_objectGUID_isString(v2)) {
277 struct ldb_val v;
278 int ret;
279 if (ldif_read_objectGUID(ldb, mem_ctx, v2, &v) != 0) {
280 /* Perhaps it wasn't a valid string after all */
281 return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
283 ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v);
284 talloc_free(v.data);
285 return ret;
287 return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
291 canonicalise a objectGUID
293 static int ldb_canonicalise_objectGUID(struct ldb_context *ldb, void *mem_ctx,
294 const struct ldb_val *in, struct ldb_val *out)
296 if (ldb_comparision_objectGUID_isString(in)) {
297 if (ldif_read_objectGUID(ldb, mem_ctx, in, out) != 0) {
298 /* Perhaps it wasn't a valid string after all */
299 return ldb_handler_copy(ldb, mem_ctx, in, out);
301 return 0;
303 return ldb_handler_copy(ldb, mem_ctx, in, out);
308 convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob
310 static int ldif_read_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx,
311 const struct ldb_val *in, struct ldb_val *out)
313 struct security_descriptor *sd;
314 enum ndr_err_code ndr_err;
316 sd = sddl_decode(mem_ctx, (const char *)in->data, NULL);
317 if (sd == NULL) {
318 return -1;
320 ndr_err = ndr_push_struct_blob(out, mem_ctx, NULL, sd,
321 (ndr_push_flags_fn_t)ndr_push_security_descriptor);
322 talloc_free(sd);
323 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
324 return -1;
326 return 0;
330 convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format)
332 static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx,
333 const struct ldb_val *in, struct ldb_val *out)
335 struct security_descriptor *sd;
336 enum ndr_err_code ndr_err;
338 sd = talloc(mem_ctx, struct security_descriptor);
339 if (sd == NULL) {
340 return -1;
342 /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
343 ndr_err = ndr_pull_struct_blob(in, sd, NULL, sd,
344 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
345 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
346 talloc_free(sd);
347 return -1;
349 out->data = (uint8_t *)sddl_encode(mem_ctx, sd, NULL);
350 talloc_free(sd);
351 if (out->data == NULL) {
352 return -1;
354 out->length = strlen((const char *)out->data);
355 return 0;
359 canonicalise an objectCategory. We use the short form as the cannoical form:
360 cn=Person,cn=Schema,cn=Configuration,<basedn> becomes 'person'
363 static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx,
364 const struct ldb_val *in, struct ldb_val *out)
366 struct ldb_dn *dn1 = NULL;
367 const struct dsdb_schema *schema = dsdb_get_schema(ldb);
368 const struct dsdb_class *class;
369 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
370 if (!tmp_ctx) {
371 return LDB_ERR_OPERATIONS_ERROR;
374 if (!schema) {
375 *out = data_blob_talloc(mem_ctx, in->data, in->length);
376 if (in->data && !out->data) {
377 return LDB_ERR_OPERATIONS_ERROR;
379 return LDB_SUCCESS;
381 dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, in);
382 if ( ! ldb_dn_validate(dn1)) {
383 const char *lDAPDisplayName = talloc_strndup(tmp_ctx, (char *)in->data, in->length);
384 class = dsdb_class_by_lDAPDisplayName(schema, lDAPDisplayName);
385 if (class) {
386 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb,
387 class->defaultObjectCategory);
388 *out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn));
389 talloc_free(tmp_ctx);
391 if (!out->data) {
392 return LDB_ERR_OPERATIONS_ERROR;
394 return LDB_SUCCESS;
395 } else {
396 *out = data_blob_talloc(mem_ctx, in->data, in->length);
397 talloc_free(tmp_ctx);
399 if (in->data && !out->data) {
400 return LDB_ERR_OPERATIONS_ERROR;
402 return LDB_SUCCESS;
405 *out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn1));
406 talloc_free(tmp_ctx);
408 if (!out->data) {
409 return LDB_ERR_OPERATIONS_ERROR;
411 return LDB_SUCCESS;
414 static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx,
415 const struct ldb_val *v1,
416 const struct ldb_val *v2)
419 int ret, ret1, ret2;
420 struct ldb_val v1_canon, v2_canon;
421 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
423 /* I could try and bail if tmp_ctx was NULL, but what return
424 * value would I use?
426 * It seems easier to continue on the NULL context
428 ret1 = ldif_canonicalise_objectCategory(ldb, tmp_ctx, v1, &v1_canon);
429 ret2 = ldif_canonicalise_objectCategory(ldb, tmp_ctx, v2, &v2_canon);
431 if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) {
432 ret = data_blob_cmp(&v1_canon, &v2_canon);
433 } else {
434 ret = data_blob_cmp(v1, v2);
436 talloc_free(tmp_ctx);
437 return ret;
441 convert a ldif formatted prefixMap to a NDR formatted blob
443 static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
444 const struct ldb_val *in, struct ldb_val *out)
446 struct prefixMapBlob *blob;
447 enum ndr_err_code ndr_err;
448 char *string, *line, *p, *oid;
450 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
452 if (tmp_ctx == NULL) {
453 return -1;
456 blob = talloc_zero(tmp_ctx, struct prefixMapBlob);
457 if (blob == NULL) {
458 talloc_free(blob);
459 return -1;
462 blob->version = PREFIX_MAP_VERSION_DSDB;
464 string = talloc_strndup(mem_ctx, (const char *)in->data, in->length);
465 if (string == NULL) {
466 talloc_free(blob);
467 return -1;
470 line = string;
471 while (line && line[0]) {
472 p=strchr(line, ';');
473 if (p) {
474 p[0] = '\0';
475 } else {
476 p=strchr(line, '\n');
477 if (p) {
478 p[0] = '\0';
481 /* allow a traling seperator */
482 if (line == p) {
483 break;
486 blob->ctr.dsdb.mappings = talloc_realloc(blob,
487 blob->ctr.dsdb.mappings,
488 struct drsuapi_DsReplicaOIDMapping,
489 blob->ctr.dsdb.num_mappings+1);
490 if (!blob->ctr.dsdb.mappings) {
491 talloc_free(tmp_ctx);
492 return -1;
495 blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix = strtoul(line, &oid, 10);
497 if (oid[0] != ':') {
498 talloc_free(tmp_ctx);
499 return -1;
502 /* we know there must be at least ":" */
503 oid++;
505 blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.oid
506 = talloc_strdup(blob->ctr.dsdb.mappings, oid);
508 blob->ctr.dsdb.num_mappings++;
510 /* Now look past the terminator we added above */
511 if (p) {
512 line = p + 1;
513 } else {
514 line = NULL;
518 ndr_err = ndr_push_struct_blob(out, mem_ctx,
519 lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
520 blob,
521 (ndr_push_flags_fn_t)ndr_push_prefixMapBlob);
522 talloc_free(tmp_ctx);
523 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
524 return -1;
526 return 0;
530 convert a NDR formatted blob to a ldif formatted prefixMap
532 static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx,
533 const struct ldb_val *in, struct ldb_val *out)
535 struct prefixMapBlob *blob;
536 enum ndr_err_code ndr_err;
537 char *string;
538 uint32_t i;
540 blob = talloc(mem_ctx, struct prefixMapBlob);
541 if (blob == NULL) {
542 return -1;
544 ndr_err = ndr_pull_struct_blob_all(in, blob,
545 lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
546 blob,
547 (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
548 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
549 talloc_free(blob);
550 return -1;
552 if (blob->version != PREFIX_MAP_VERSION_DSDB) {
553 return -1;
555 string = talloc_strdup(mem_ctx, "");
556 if (string == NULL) {
557 return -1;
560 for (i=0; i < blob->ctr.dsdb.num_mappings; i++) {
561 if (i > 0) {
562 string = talloc_asprintf_append(string, ";");
564 string = talloc_asprintf_append(string, "%u:%s",
565 blob->ctr.dsdb.mappings[i].id_prefix,
566 blob->ctr.dsdb.mappings[i].oid.oid);
567 if (string == NULL) {
568 return -1;
572 talloc_free(blob);
573 *out = data_blob_string_const(string);
574 return 0;
577 static bool ldif_comparision_prefixMap_isString(const struct ldb_val *v)
579 if (v->length < 4) {
580 return true;
583 if (IVAL(v->data, 0) == PREFIX_MAP_VERSION_DSDB) {
584 return false;
587 return true;
591 canonicalise a prefixMap
593 static int ldif_canonicalise_prefixMap(struct ldb_context *ldb, void *mem_ctx,
594 const struct ldb_val *in, struct ldb_val *out)
596 if (ldif_comparision_prefixMap_isString(in)) {
597 return ldif_read_prefixMap(ldb, mem_ctx, in, out);
599 return ldb_handler_copy(ldb, mem_ctx, in, out);
602 static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx,
603 const struct ldb_val *v1,
604 const struct ldb_val *v2)
607 int ret, ret1, ret2;
608 struct ldb_val v1_canon, v2_canon;
609 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
611 /* I could try and bail if tmp_ctx was NULL, but what return
612 * value would I use?
614 * It seems easier to continue on the NULL context
616 ret1 = ldif_canonicalise_prefixMap(ldb, tmp_ctx, v1, &v1_canon);
617 ret2 = ldif_canonicalise_prefixMap(ldb, tmp_ctx, v2, &v2_canon);
619 if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) {
620 ret = data_blob_cmp(&v1_canon, &v2_canon);
621 } else {
622 ret = data_blob_cmp(v1, v2);
624 talloc_free(tmp_ctx);
625 return ret;
628 static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx,
629 const struct ldb_val *in, struct ldb_val *out)
631 *out = data_blob_string_const(data_blob_hex_string(mem_ctx, in));
632 if (!out->data) {
633 return -1;
635 return 0;
639 #define LDB_SYNTAX_SAMBA_GUID "LDB_SYNTAX_SAMBA_GUID"
640 #define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY"
641 #define LDB_SYNTAX_SAMBA_PREFIX_MAP "LDB_SYNTAX_SAMBA_PREFIX_MAP"
643 static const struct ldb_schema_syntax samba_syntaxes[] = {
645 .name = LDB_SYNTAX_SAMBA_SID,
646 .ldif_read_fn = ldif_read_objectSid,
647 .ldif_write_fn = ldif_write_objectSid,
648 .canonicalise_fn = ldb_canonicalise_objectSid,
649 .comparison_fn = ldb_comparison_objectSid
651 .name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
652 .ldif_read_fn = ldif_read_ntSecurityDescriptor,
653 .ldif_write_fn = ldif_write_ntSecurityDescriptor,
654 .canonicalise_fn = ldb_handler_copy,
655 .comparison_fn = ldb_comparison_binary
657 .name = LDB_SYNTAX_SAMBA_GUID,
658 .ldif_read_fn = ldif_read_objectGUID,
659 .ldif_write_fn = ldif_write_objectGUID,
660 .canonicalise_fn = ldb_canonicalise_objectGUID,
661 .comparison_fn = ldb_comparison_objectGUID
663 .name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY,
664 .ldif_read_fn = ldb_handler_copy,
665 .ldif_write_fn = ldb_handler_copy,
666 .canonicalise_fn = ldif_canonicalise_objectCategory,
667 .comparison_fn = ldif_comparison_objectCategory
669 .name = LDB_SYNTAX_SAMBA_PREFIX_MAP,
670 .ldif_read_fn = ldif_read_prefixMap,
671 .ldif_write_fn = ldif_write_prefixMap,
672 .canonicalise_fn = ldif_canonicalise_prefixMap,
673 .comparison_fn = ldif_comparison_prefixMap
677 static const struct ldb_dn_extended_syntax samba_dn_syntax[] = {
679 .name = "SID",
680 .read_fn = extended_dn_read_SID,
681 .write_clear_fn = ldif_write_objectSid,
682 .write_hex_fn = extended_dn_write_hex
684 .name = "GUID",
685 .read_fn = extended_dn_read_GUID,
686 .write_clear_fn = ldif_write_objectGUID,
687 .write_hex_fn = extended_dn_write_hex
689 .name = "WKGUID",
690 .read_fn = ldb_handler_copy,
691 .write_clear_fn = ldb_handler_copy,
692 .write_hex_fn = ldb_handler_copy
696 static const struct {
697 const char *name;
698 const char *syntax;
699 } samba_attributes[] = {
700 { "objectSid", LDB_SYNTAX_SAMBA_SID },
701 { "securityIdentifier", LDB_SYNTAX_SAMBA_SID },
702 { "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR },
703 { "objectGUID", LDB_SYNTAX_SAMBA_GUID },
704 { "invocationId", LDB_SYNTAX_SAMBA_GUID },
705 { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID },
706 { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID },
707 { "parentGUID", LDB_SYNTAX_SAMBA_GUID },
708 { "siteGUID", LDB_SYNTAX_SAMBA_GUID },
709 { "pKTGUID", LDB_SYNTAX_SAMBA_GUID },
710 { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID },
711 { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID },
712 { "netbootGUID", LDB_SYNTAX_SAMBA_GUID },
713 { "objectCategory", LDB_SYNTAX_SAMBA_OBJECT_CATEGORY },
714 { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP }
717 const struct ldb_schema_syntax *ldb_samba_syntax_by_name(struct ldb_context *ldb, const char *name)
719 uint32_t j;
720 const struct ldb_schema_syntax *s = NULL;
722 for (j=0; j < ARRAY_SIZE(samba_syntaxes); j++) {
723 if (strcmp(name, samba_syntaxes[j].name) == 0) {
724 s = &samba_syntaxes[j];
725 break;
728 return s;
733 register the samba ldif handlers
735 int ldb_register_samba_handlers(struct ldb_context *ldb)
737 uint32_t i;
739 for (i=0; i < ARRAY_SIZE(samba_attributes); i++) {
740 int ret;
741 const struct ldb_schema_syntax *s = NULL;
743 s = ldb_samba_syntax_by_name(ldb, samba_attributes[i].syntax);
745 if (!s) {
746 s = ldb_standard_syntax_by_name(ldb, samba_attributes[i].syntax);
749 if (!s) {
750 return -1;
753 ret = ldb_schema_attribute_add_with_syntax(ldb, samba_attributes[i].name, LDB_ATTR_FLAG_FIXED, s);
754 if (ret != LDB_SUCCESS) {
755 return ret;
759 for (i=0; i < ARRAY_SIZE(samba_dn_syntax); i++) {
760 int ret;
761 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &samba_dn_syntax[i]);
762 if (ret != LDB_SUCCESS) {
763 return ret;
769 return LDB_SUCCESS;