2 ldb database library - ldif handlers for Samba
4 Copyright (C) Andrew Tridgell 2005
5 Copyright (C) Andrew Bartlett 2006-2009
6 Copyright (C) Matthias Dieter Wallnöfer 2009
7 ** NOTE! The following LGPL license applies to the ldb
8 ** library. This does NOT imply that all of Samba is released
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Lesser General Public
13 License as published by the Free Software Foundation; either
14 version 3 of the License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 #include "lib/ldb/include/ldb.h"
27 #include "lib/ldb/include/ldb_module.h"
28 #include "ldb_handlers.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "librpc/gen_ndr/ndr_misc.h"
32 #include "librpc/gen_ndr/ndr_drsblobs.h"
33 #include "librpc/ndr/libndr.h"
34 #include "libcli/security/security.h"
35 #include "param/param.h"
36 #include "../lib/util/asn1.h"
39 use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob
41 static int ldif_write_NDR(struct ldb_context
*ldb
, void *mem_ctx
,
42 const struct ldb_val
*in
, struct ldb_val
*out
,
44 ndr_pull_flags_fn_t pull_fn
,
45 ndr_print_fn_t print_fn
)
48 enum ndr_err_code err
;
49 if (!(ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
)) {
50 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
52 p
= talloc_size(mem_ctx
, struct_size
);
53 err
= ndr_pull_struct_blob(in
, mem_ctx
,
54 lp_iconv_convenience(ldb_get_opaque(ldb
, "loadparm")),
56 if (err
!= NDR_ERR_SUCCESS
) {
58 out
->data
= (uint8_t *)talloc_strdup(mem_ctx
, "<Unable to decode binary data>");
59 out
->length
= strlen((const char *)out
->data
);
62 out
->data
= (uint8_t *)ndr_print_struct_string(mem_ctx
, print_fn
, "NDR", p
);
64 if (out
->data
== NULL
) {
65 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
67 out
->length
= strlen((char *)out
->data
);
72 convert a ldif formatted objectSid to a NDR formatted blob
74 static int ldif_read_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
75 const struct ldb_val
*in
, struct ldb_val
*out
)
77 enum ndr_err_code ndr_err
;
79 sid
= dom_sid_parse_length(mem_ctx
, in
);
83 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
, NULL
, sid
,
84 (ndr_push_flags_fn_t
)ndr_push_dom_sid
);
86 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
93 convert a NDR formatted blob to a ldif formatted objectSid
95 int ldif_write_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
96 const struct ldb_val
*in
, struct ldb_val
*out
)
99 enum ndr_err_code ndr_err
;
101 sid
= talloc(mem_ctx
, struct dom_sid
);
105 ndr_err
= ndr_pull_struct_blob_all(in
, sid
, NULL
, sid
,
106 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
107 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
111 *out
= data_blob_string_const(dom_sid_string(mem_ctx
, sid
));
113 if (out
->data
== NULL
) {
119 bool ldif_comparision_objectSid_isString(const struct ldb_val
*v
)
125 if (strncmp("S-", (const char *)v
->data
, 2) != 0) return false;
131 compare two objectSids
133 static int ldif_comparison_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
134 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
136 if (ldif_comparision_objectSid_isString(v1
) && ldif_comparision_objectSid_isString(v2
)) {
137 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
138 } else if (ldif_comparision_objectSid_isString(v1
)
139 && !ldif_comparision_objectSid_isString(v2
)) {
142 if (ldif_read_objectSid(ldb
, mem_ctx
, v1
, &v
) != 0) {
143 /* Perhaps not a string after all */
144 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
146 ret
= ldb_comparison_binary(ldb
, mem_ctx
, &v
, v2
);
149 } else if (!ldif_comparision_objectSid_isString(v1
)
150 && ldif_comparision_objectSid_isString(v2
)) {
153 if (ldif_read_objectSid(ldb
, mem_ctx
, v2
, &v
) != 0) {
154 /* Perhaps not a string after all */
155 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
157 ret
= ldb_comparison_binary(ldb
, mem_ctx
, v1
, &v
);
161 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
165 canonicalise a objectSid
167 static int ldif_canonicalise_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
168 const struct ldb_val
*in
, struct ldb_val
*out
)
170 if (ldif_comparision_objectSid_isString(in
)) {
171 if (ldif_read_objectSid(ldb
, mem_ctx
, in
, out
) != 0) {
172 /* Perhaps not a string after all */
173 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
177 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
180 static int extended_dn_read_SID(struct ldb_context
*ldb
, void *mem_ctx
,
181 const struct ldb_val
*in
, struct ldb_val
*out
)
184 enum ndr_err_code ndr_err
;
185 if (ldif_comparision_objectSid_isString(in
)) {
186 if (ldif_read_objectSid(ldb
, mem_ctx
, in
, out
) == 0) {
191 /* Perhaps not a string after all */
192 *out
= data_blob_talloc(mem_ctx
, NULL
, in
->length
/2+1);
198 (*out
).length
= strhex_to_str((char *)out
->data
, out
->length
,
199 (const char *)in
->data
, in
->length
);
201 /* Check it looks like a SID */
202 ndr_err
= ndr_pull_struct_blob_all(out
, mem_ctx
, NULL
, &sid
,
203 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
204 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
211 convert a ldif formatted objectGUID to a NDR formatted blob
213 static int ldif_read_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
214 const struct ldb_val
*in
, struct ldb_val
*out
)
218 enum ndr_err_code ndr_err
;
220 status
= GUID_from_data_blob(in
, &guid
);
221 if (!NT_STATUS_IS_OK(status
)) {
225 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
, NULL
, &guid
,
226 (ndr_push_flags_fn_t
)ndr_push_GUID
);
227 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
234 convert a NDR formatted blob to a ldif formatted objectGUID
236 static int ldif_write_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
237 const struct ldb_val
*in
, struct ldb_val
*out
)
240 enum ndr_err_code ndr_err
;
241 ndr_err
= ndr_pull_struct_blob_all(in
, mem_ctx
, NULL
, &guid
,
242 (ndr_pull_flags_fn_t
)ndr_pull_GUID
);
243 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
246 out
->data
= (uint8_t *)GUID_string(mem_ctx
, &guid
);
247 if (out
->data
== NULL
) {
250 out
->length
= strlen((const char *)out
->data
);
254 static bool ldif_comparision_objectGUID_isString(const struct ldb_val
*v
)
256 if (v
->length
!= 36 && v
->length
!= 38) return false;
258 /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */
262 static int extended_dn_read_GUID(struct ldb_context
*ldb
, void *mem_ctx
,
263 const struct ldb_val
*in
, struct ldb_val
*out
)
266 enum ndr_err_code ndr_err
;
267 if (in
->length
== 36 && ldif_read_objectGUID(ldb
, mem_ctx
, in
, out
) == 0) {
271 /* Try as 'hex' form */
272 if (in
->length
!= 32) {
276 *out
= data_blob_talloc(mem_ctx
, NULL
, in
->length
/2+1);
282 (*out
).length
= strhex_to_str((char *)out
->data
, out
->length
,
283 (const char *)in
->data
, in
->length
);
285 /* Check it looks like a GUID */
286 ndr_err
= ndr_pull_struct_blob_all(out
, mem_ctx
, NULL
, &guid
,
287 (ndr_pull_flags_fn_t
)ndr_pull_GUID
);
288 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
295 compare two objectGUIDs
297 static int ldif_comparison_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
298 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
300 if (ldif_comparision_objectGUID_isString(v1
) && ldif_comparision_objectGUID_isString(v2
)) {
301 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
302 } else if (ldif_comparision_objectGUID_isString(v1
)
303 && !ldif_comparision_objectGUID_isString(v2
)) {
306 if (ldif_read_objectGUID(ldb
, mem_ctx
, v1
, &v
) != 0) {
307 /* Perhaps it wasn't a valid string after all */
308 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
310 ret
= ldb_comparison_binary(ldb
, mem_ctx
, &v
, v2
);
313 } else if (!ldif_comparision_objectGUID_isString(v1
)
314 && ldif_comparision_objectGUID_isString(v2
)) {
317 if (ldif_read_objectGUID(ldb
, mem_ctx
, v2
, &v
) != 0) {
318 /* Perhaps it wasn't a valid string after all */
319 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
321 ret
= ldb_comparison_binary(ldb
, mem_ctx
, v1
, &v
);
325 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
329 canonicalise a objectGUID
331 static int ldif_canonicalise_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
332 const struct ldb_val
*in
, struct ldb_val
*out
)
334 if (ldif_comparision_objectGUID_isString(in
)) {
335 if (ldif_read_objectGUID(ldb
, mem_ctx
, in
, out
) != 0) {
336 /* Perhaps it wasn't a valid string after all */
337 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
341 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
346 convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob
348 static int ldif_read_ntSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
349 const struct ldb_val
*in
, struct ldb_val
*out
)
351 struct security_descriptor
*sd
;
352 enum ndr_err_code ndr_err
;
354 sd
= talloc(mem_ctx
, struct security_descriptor
);
359 ndr_err
= ndr_pull_struct_blob(in
, sd
, NULL
, sd
,
360 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
361 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
362 /* If this does not parse, then it is probably SDDL, and we should try it that way */
364 const struct dom_sid
*sid
= samdb_domain_sid(ldb
);
366 sd
= sddl_decode(mem_ctx
, (const char *)in
->data
, sid
);
372 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
, NULL
, sd
,
373 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
);
375 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
383 convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format)
385 static int ldif_write_ntSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
386 const struct ldb_val
*in
, struct ldb_val
*out
)
388 struct security_descriptor
*sd
;
389 enum ndr_err_code ndr_err
;
391 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
392 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
393 sizeof(struct security_descriptor
),
394 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
,
395 (ndr_print_fn_t
)ndr_print_security_descriptor
);
399 sd
= talloc(mem_ctx
, struct security_descriptor
);
403 /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
404 ndr_err
= ndr_pull_struct_blob(in
, sd
, NULL
, sd
,
405 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
406 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
410 out
->data
= (uint8_t *)sddl_encode(mem_ctx
, sd
, NULL
);
412 if (out
->data
== NULL
) {
415 out
->length
= strlen((const char *)out
->data
);
420 canonicalise an objectCategory. We use the short form as the cannoical form:
421 cn=Person,cn=Schema,cn=Configuration,<basedn> becomes 'person'
424 static int ldif_canonicalise_objectCategory(struct ldb_context
*ldb
, void *mem_ctx
,
425 const struct ldb_val
*in
, struct ldb_val
*out
)
427 struct ldb_dn
*dn1
= NULL
;
428 const struct dsdb_schema
*schema
= dsdb_get_schema(ldb
);
429 const struct dsdb_class
*sclass
;
430 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
432 return LDB_ERR_OPERATIONS_ERROR
;
436 talloc_free(tmp_ctx
);
437 *out
= data_blob_talloc(mem_ctx
, in
->data
, in
->length
);
438 if (in
->data
&& !out
->data
) {
439 return LDB_ERR_OPERATIONS_ERROR
;
443 dn1
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, in
);
444 if ( ! ldb_dn_validate(dn1
)) {
445 const char *lDAPDisplayName
= talloc_strndup(tmp_ctx
, (char *)in
->data
, in
->length
);
446 sclass
= dsdb_class_by_lDAPDisplayName(schema
, lDAPDisplayName
);
448 struct ldb_dn
*dn
= ldb_dn_new(mem_ctx
, ldb
,
449 sclass
->defaultObjectCategory
);
450 *out
= data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx
, dn
));
451 talloc_free(tmp_ctx
);
454 return LDB_ERR_OPERATIONS_ERROR
;
458 *out
= data_blob_talloc(mem_ctx
, in
->data
, in
->length
);
459 talloc_free(tmp_ctx
);
461 if (in
->data
&& !out
->data
) {
462 return LDB_ERR_OPERATIONS_ERROR
;
467 *out
= data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx
, dn1
));
468 talloc_free(tmp_ctx
);
471 return LDB_ERR_OPERATIONS_ERROR
;
476 static int ldif_comparison_objectCategory(struct ldb_context
*ldb
, void *mem_ctx
,
477 const struct ldb_val
*v1
,
478 const struct ldb_val
*v2
)
480 return ldb_any_comparison(ldb
, mem_ctx
, ldif_canonicalise_objectCategory
,
485 convert a ldif formatted prefixMap to a NDR formatted blob
487 static int ldif_read_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
488 const struct ldb_val
*in
, struct ldb_val
*out
)
490 struct prefixMapBlob
*blob
;
491 enum ndr_err_code ndr_err
;
492 char *string
, *line
, *p
, *oid
;
495 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
497 if (tmp_ctx
== NULL
) {
501 blob
= talloc_zero(tmp_ctx
, struct prefixMapBlob
);
507 blob
->version
= PREFIX_MAP_VERSION_DSDB
;
509 string
= talloc_strndup(mem_ctx
, (const char *)in
->data
, in
->length
);
510 if (string
== NULL
) {
516 while (line
&& line
[0]) {
521 p
=strchr(line
, '\n');
526 /* allow a traling seperator */
531 blob
->ctr
.dsdb
.mappings
= talloc_realloc(blob
,
532 blob
->ctr
.dsdb
.mappings
,
533 struct drsuapi_DsReplicaOIDMapping
,
534 blob
->ctr
.dsdb
.num_mappings
+1);
535 if (!blob
->ctr
.dsdb
.mappings
) {
536 talloc_free(tmp_ctx
);
540 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].id_prefix
= strtoul(line
, &oid
, 10);
543 talloc_free(tmp_ctx
);
547 /* we know there must be at least ":" */
550 if (!ber_write_partial_OID_String(blob
->ctr
.dsdb
.mappings
, &oid_blob
, oid
)) {
551 talloc_free(tmp_ctx
);
554 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].oid
.length
= oid_blob
.length
;
555 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].oid
.binary_oid
= oid_blob
.data
;
557 blob
->ctr
.dsdb
.num_mappings
++;
559 /* Now look past the terminator we added above */
567 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
,
568 lp_iconv_convenience(ldb_get_opaque(ldb
, "loadparm")),
570 (ndr_push_flags_fn_t
)ndr_push_prefixMapBlob
);
571 talloc_free(tmp_ctx
);
572 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
579 convert a NDR formatted blob to a ldif formatted prefixMap
581 static int ldif_write_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
582 const struct ldb_val
*in
, struct ldb_val
*out
)
584 struct prefixMapBlob
*blob
;
585 enum ndr_err_code ndr_err
;
589 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
590 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
591 sizeof(struct prefixMapBlob
),
592 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
,
593 (ndr_print_fn_t
)ndr_print_prefixMapBlob
);
597 blob
= talloc(mem_ctx
, struct prefixMapBlob
);
601 ndr_err
= ndr_pull_struct_blob_all(in
, blob
,
602 lp_iconv_convenience(ldb_get_opaque(ldb
, "loadparm")),
604 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
);
605 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
608 if (blob
->version
!= PREFIX_MAP_VERSION_DSDB
) {
611 string
= talloc_strdup(mem_ctx
, "");
612 if (string
== NULL
) {
616 for (i
=0; i
< blob
->ctr
.dsdb
.num_mappings
; i
++) {
618 const char *partial_oid
= NULL
;
621 string
= talloc_asprintf_append(string
, ";");
624 oid_blob
= data_blob_const(blob
->ctr
.dsdb
.mappings
[i
].oid
.binary_oid
,
625 blob
->ctr
.dsdb
.mappings
[i
].oid
.length
);
626 if (!ber_read_partial_OID_String(blob
, oid_blob
, &partial_oid
)) {
627 DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X",
628 blob
->ctr
.dsdb
.mappings
[i
].id_prefix
));
631 string
= talloc_asprintf_append(string
, "%u:%s",
632 blob
->ctr
.dsdb
.mappings
[i
].id_prefix
,
634 talloc_free(discard_const(partial_oid
));
635 if (string
== NULL
) {
641 *out
= data_blob_string_const(string
);
649 static bool ldif_comparision_prefixMap_isString(const struct ldb_val
*v
)
655 if (IVAL(v
->data
, 0) == PREFIX_MAP_VERSION_DSDB
) {
663 canonicalise a prefixMap
665 static int ldif_canonicalise_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
666 const struct ldb_val
*in
, struct ldb_val
*out
)
668 if (ldif_comparision_prefixMap_isString(in
)) {
669 return ldif_read_prefixMap(ldb
, mem_ctx
, in
, out
);
671 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
674 static int ldif_comparison_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
675 const struct ldb_val
*v1
,
676 const struct ldb_val
*v2
)
678 return ldb_any_comparison(ldb
, mem_ctx
, ldif_canonicalise_prefixMap
,
682 /* Canonicalisation of two 32-bit integers */
683 static int ldif_canonicalise_int32(struct ldb_context
*ldb
, void *mem_ctx
,
684 const struct ldb_val
*in
, struct ldb_val
*out
)
687 /* We've to use "strtoll" here to have the intended overflows.
688 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
689 int32_t i
= (int32_t) strtoll((char *)in
->data
, &end
, 0);
693 out
->data
= (uint8_t *) talloc_asprintf(mem_ctx
, "%d", i
);
694 if (out
->data
== NULL
) {
697 out
->length
= strlen((char *)out
->data
);
701 /* Comparison of two 32-bit integers */
702 static int ldif_comparison_int32(struct ldb_context
*ldb
, void *mem_ctx
,
703 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
705 /* We've to use "strtoll" here to have the intended overflows.
706 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
707 return (int32_t) strtoll((char *)v1
->data
, NULL
, 0)
708 - (int32_t) strtoll((char *)v2
->data
, NULL
, 0);
712 convert a NDR formatted blob to a ldif formatted repsFromTo
714 static int ldif_write_repsFromTo(struct ldb_context
*ldb
, void *mem_ctx
,
715 const struct ldb_val
*in
, struct ldb_val
*out
)
717 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
718 sizeof(struct repsFromToBlob
),
719 (ndr_pull_flags_fn_t
)ndr_pull_repsFromToBlob
,
720 (ndr_print_fn_t
)ndr_print_repsFromToBlob
);
724 convert a NDR formatted blob to a ldif formatted replPropertyMetaData
726 static int ldif_write_replPropertyMetaData(struct ldb_context
*ldb
, void *mem_ctx
,
727 const struct ldb_val
*in
, struct ldb_val
*out
)
729 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
730 sizeof(struct replPropertyMetaDataBlob
),
731 (ndr_pull_flags_fn_t
)ndr_pull_replPropertyMetaDataBlob
,
732 (ndr_print_fn_t
)ndr_print_replPropertyMetaDataBlob
);
736 convert a NDR formatted blob to a ldif formatted replUpToDateVector
738 static int ldif_write_replUpToDateVector(struct ldb_context
*ldb
, void *mem_ctx
,
739 const struct ldb_val
*in
, struct ldb_val
*out
)
741 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
742 sizeof(struct replUpToDateVectorBlob
),
743 (ndr_pull_flags_fn_t
)ndr_pull_replUpToDateVectorBlob
,
744 (ndr_print_fn_t
)ndr_print_replUpToDateVectorBlob
);
748 static int extended_dn_write_hex(struct ldb_context
*ldb
, void *mem_ctx
,
749 const struct ldb_val
*in
, struct ldb_val
*out
)
751 *out
= data_blob_string_const(data_blob_hex_string_lower(mem_ctx
, in
));
758 static const struct ldb_schema_syntax samba_syntaxes
[] = {
760 .name
= LDB_SYNTAX_SAMBA_SID
,
761 .ldif_read_fn
= ldif_read_objectSid
,
762 .ldif_write_fn
= ldif_write_objectSid
,
763 .canonicalise_fn
= ldif_canonicalise_objectSid
,
764 .comparison_fn
= ldif_comparison_objectSid
766 .name
= LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR
,
767 .ldif_read_fn
= ldif_read_ntSecurityDescriptor
,
768 .ldif_write_fn
= ldif_write_ntSecurityDescriptor
,
769 .canonicalise_fn
= ldb_handler_copy
,
770 .comparison_fn
= ldb_comparison_binary
772 .name
= LDB_SYNTAX_SAMBA_GUID
,
773 .ldif_read_fn
= ldif_read_objectGUID
,
774 .ldif_write_fn
= ldif_write_objectGUID
,
775 .canonicalise_fn
= ldif_canonicalise_objectGUID
,
776 .comparison_fn
= ldif_comparison_objectGUID
778 .name
= LDB_SYNTAX_SAMBA_OBJECT_CATEGORY
,
779 .ldif_read_fn
= ldb_handler_copy
,
780 .ldif_write_fn
= ldb_handler_copy
,
781 .canonicalise_fn
= ldif_canonicalise_objectCategory
,
782 .comparison_fn
= ldif_comparison_objectCategory
784 .name
= LDB_SYNTAX_SAMBA_PREFIX_MAP
,
785 .ldif_read_fn
= ldif_read_prefixMap
,
786 .ldif_write_fn
= ldif_write_prefixMap
,
787 .canonicalise_fn
= ldif_canonicalise_prefixMap
,
788 .comparison_fn
= ldif_comparison_prefixMap
790 .name
= LDB_SYNTAX_SAMBA_INT32
,
791 .ldif_read_fn
= ldb_handler_copy
,
792 .ldif_write_fn
= ldb_handler_copy
,
793 .canonicalise_fn
= ldif_canonicalise_int32
,
794 .comparison_fn
= ldif_comparison_int32
796 .name
= LDB_SYNTAX_SAMBA_REPSFROMTO
,
797 .ldif_read_fn
= ldb_handler_copy
,
798 .ldif_write_fn
= ldif_write_repsFromTo
,
799 .canonicalise_fn
= ldb_handler_copy
,
800 .comparison_fn
= ldb_comparison_binary
802 .name
= LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA
,
803 .ldif_read_fn
= ldb_handler_copy
,
804 .ldif_write_fn
= ldif_write_replPropertyMetaData
,
805 .canonicalise_fn
= ldb_handler_copy
,
806 .comparison_fn
= ldb_comparison_binary
808 .name
= LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR
,
809 .ldif_read_fn
= ldb_handler_copy
,
810 .ldif_write_fn
= ldif_write_replUpToDateVector
,
811 .canonicalise_fn
= ldb_handler_copy
,
812 .comparison_fn
= ldb_comparison_binary
814 .name
= DSDB_SYNTAX_BINARY_DN
,
815 .ldif_read_fn
= ldb_handler_copy
,
816 .ldif_write_fn
= ldb_handler_copy
,
817 .canonicalise_fn
= dsdb_dn_binary_canonicalise
,
818 .comparison_fn
= dsdb_dn_binary_comparison
820 .name
= DSDB_SYNTAX_STRING_DN
,
821 .ldif_read_fn
= ldb_handler_copy
,
822 .ldif_write_fn
= ldb_handler_copy
,
823 .canonicalise_fn
= dsdb_dn_string_canonicalise
,
824 .comparison_fn
= dsdb_dn_string_comparison
828 static const struct ldb_dn_extended_syntax samba_dn_syntax
[] = {
831 .read_fn
= extended_dn_read_SID
,
832 .write_clear_fn
= ldif_write_objectSid
,
833 .write_hex_fn
= extended_dn_write_hex
836 .read_fn
= extended_dn_read_GUID
,
837 .write_clear_fn
= ldif_write_objectGUID
,
838 .write_hex_fn
= extended_dn_write_hex
841 .read_fn
= ldb_handler_copy
,
842 .write_clear_fn
= ldb_handler_copy
,
843 .write_hex_fn
= ldb_handler_copy
847 /* TODO: Should be dynamic at some point */
848 static const struct {
851 } samba_attributes
[] = {
852 { "objectSid", LDB_SYNTAX_SAMBA_SID
},
853 { "securityIdentifier", LDB_SYNTAX_SAMBA_SID
},
854 { "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR
},
855 { "objectGUID", LDB_SYNTAX_SAMBA_GUID
},
856 { "invocationId", LDB_SYNTAX_SAMBA_GUID
},
857 { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID
},
858 { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID
},
859 { "parentGUID", LDB_SYNTAX_SAMBA_GUID
},
860 { "siteGUID", LDB_SYNTAX_SAMBA_GUID
},
861 { "pKTGUID", LDB_SYNTAX_SAMBA_GUID
},
862 { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID
},
863 { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID
},
864 { "netbootGUID", LDB_SYNTAX_SAMBA_GUID
},
865 { "objectCategory", LDB_SYNTAX_SAMBA_OBJECT_CATEGORY
},
866 { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP
},
867 { "repsFrom", LDB_SYNTAX_SAMBA_REPSFROMTO
},
868 { "repsTo", LDB_SYNTAX_SAMBA_REPSFROMTO
},
869 { "replPropertyMetaData", LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA
},
870 { "replUpToDateVector", LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR
},
873 const struct ldb_schema_syntax
*ldb_samba_syntax_by_name(struct ldb_context
*ldb
, const char *name
)
876 const struct ldb_schema_syntax
*s
= NULL
;
878 for (j
=0; j
< ARRAY_SIZE(samba_syntaxes
); j
++) {
879 if (strcmp(name
, samba_syntaxes
[j
].name
) == 0) {
880 s
= &samba_syntaxes
[j
];
887 const struct ldb_schema_syntax
*ldb_samba_syntax_by_lDAPDisplayName(struct ldb_context
*ldb
, const char *name
)
890 const struct ldb_schema_syntax
*s
= NULL
;
892 for (j
=0; j
< ARRAY_SIZE(samba_attributes
); j
++) {
893 if (strcmp(samba_attributes
[j
].name
, name
) == 0) {
894 s
= ldb_samba_syntax_by_name(ldb
, samba_attributes
[j
].syntax
);
903 register the samba ldif handlers
905 int ldb_register_samba_handlers(struct ldb_context
*ldb
)
909 for (i
=0; i
< ARRAY_SIZE(samba_attributes
); i
++) {
911 const struct ldb_schema_syntax
*s
= NULL
;
913 s
= ldb_samba_syntax_by_name(ldb
, samba_attributes
[i
].syntax
);
916 s
= ldb_standard_syntax_by_name(ldb
, samba_attributes
[i
].syntax
);
923 ret
= ldb_schema_attribute_add_with_syntax(ldb
, samba_attributes
[i
].name
, LDB_ATTR_FLAG_FIXED
, s
);
924 if (ret
!= LDB_SUCCESS
) {
929 for (i
=0; i
< ARRAY_SIZE(samba_dn_syntax
); i
++) {
931 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &samba_dn_syntax
[i
]);
932 if (ret
!= LDB_SUCCESS
) {