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/>.
27 #include <ldb_module.h>
28 #include "ldb_handlers.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "dsdb/common/util.h"
31 #include "librpc/gen_ndr/ndr_security.h"
32 #include "librpc/gen_ndr/ndr_misc.h"
33 #include "librpc/gen_ndr/ndr_drsblobs.h"
34 #include "librpc/gen_ndr/ndr_dnsp.h"
35 #include "librpc/ndr/libndr.h"
36 #include "libcli/security/security.h"
37 #include "param/param.h"
38 #include "../lib/util/asn1.h"
41 use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob
43 If mask_errors is true, then function succeeds but out data
44 is set to "<Unable to decode binary data>" message
46 \return 0 on success; -1 on error
48 static int ldif_write_NDR(struct ldb_context
*ldb
, void *mem_ctx
,
49 const struct ldb_val
*in
, struct ldb_val
*out
,
51 ndr_pull_flags_fn_t pull_fn
,
52 ndr_print_fn_t print_fn
,
56 enum ndr_err_code err
;
57 if (!(ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
)) {
58 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
60 p
= talloc_size(mem_ctx
, struct_size
);
61 err
= ndr_pull_struct_blob(in
, mem_ctx
,
63 if (err
!= NDR_ERR_SUCCESS
) {
64 /* fail in not in mask_error mode */
69 out
->data
= (uint8_t *)talloc_strdup(mem_ctx
, "<Unable to decode binary data>");
70 out
->length
= strlen((const char *)out
->data
);
73 out
->data
= (uint8_t *)ndr_print_struct_string(mem_ctx
, print_fn
, "NDR", p
);
75 if (out
->data
== NULL
) {
76 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
78 out
->length
= strlen((char *)out
->data
);
83 convert a ldif formatted objectSid to a NDR formatted blob
85 static int ldif_read_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
86 const struct ldb_val
*in
, struct ldb_val
*out
)
88 enum ndr_err_code ndr_err
;
90 sid
= dom_sid_parse_length(mem_ctx
, in
);
94 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
, sid
,
95 (ndr_push_flags_fn_t
)ndr_push_dom_sid
);
97 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
104 convert a NDR formatted blob to a ldif formatted objectSid
106 int ldif_write_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
107 const struct ldb_val
*in
, struct ldb_val
*out
)
110 enum ndr_err_code ndr_err
;
112 ndr_err
= ndr_pull_struct_blob_all_noalloc(in
, &sid
,
113 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
114 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
117 *out
= data_blob_string_const(dom_sid_string(mem_ctx
, &sid
));
118 if (out
->data
== NULL
) {
124 bool ldif_comparision_objectSid_isString(const struct ldb_val
*v
)
130 if (strncmp("S-", (const char *)v
->data
, 2) != 0) return false;
136 compare two objectSids
138 static int ldif_comparison_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
139 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
141 if (ldif_comparision_objectSid_isString(v1
) && ldif_comparision_objectSid_isString(v2
)) {
142 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
143 } else if (ldif_comparision_objectSid_isString(v1
)
144 && !ldif_comparision_objectSid_isString(v2
)) {
147 if (ldif_read_objectSid(ldb
, mem_ctx
, v1
, &v
) != 0) {
148 /* Perhaps not a string after all */
149 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
151 ret
= ldb_comparison_binary(ldb
, mem_ctx
, &v
, v2
);
154 } else if (!ldif_comparision_objectSid_isString(v1
)
155 && ldif_comparision_objectSid_isString(v2
)) {
158 if (ldif_read_objectSid(ldb
, mem_ctx
, v2
, &v
) != 0) {
159 /* Perhaps not a string after all */
160 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
162 ret
= ldb_comparison_binary(ldb
, mem_ctx
, v1
, &v
);
166 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
170 canonicalise a objectSid
172 static int ldif_canonicalise_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
173 const struct ldb_val
*in
, struct ldb_val
*out
)
175 if (ldif_comparision_objectSid_isString(in
)) {
176 if (ldif_read_objectSid(ldb
, mem_ctx
, in
, out
) != 0) {
177 /* Perhaps not a string after all */
178 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
182 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
185 static int extended_dn_read_SID(struct ldb_context
*ldb
, void *mem_ctx
,
186 const struct ldb_val
*in
, struct ldb_val
*out
)
189 enum ndr_err_code ndr_err
;
190 if (ldif_comparision_objectSid_isString(in
)) {
191 if (ldif_read_objectSid(ldb
, mem_ctx
, in
, out
) == 0) {
196 /* Perhaps not a string after all */
197 *out
= data_blob_talloc(mem_ctx
, NULL
, in
->length
/2+1);
203 (*out
).length
= strhex_to_str((char *)out
->data
, out
->length
,
204 (const char *)in
->data
, in
->length
);
206 /* Check it looks like a SID */
207 ndr_err
= ndr_pull_struct_blob_all_noalloc(out
, &sid
,
208 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
209 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
216 convert a ldif formatted objectGUID to a NDR formatted blob
218 static int ldif_read_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
219 const struct ldb_val
*in
, struct ldb_val
*out
)
224 status
= GUID_from_data_blob(in
, &guid
);
225 if (!NT_STATUS_IS_OK(status
)) {
229 status
= GUID_to_ndr_blob(&guid
, mem_ctx
, out
);
230 if (!NT_STATUS_IS_OK(status
)) {
237 convert a NDR formatted blob to a ldif formatted objectGUID
239 static int ldif_write_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
240 const struct ldb_val
*in
, struct ldb_val
*out
)
245 status
= GUID_from_ndr_blob(in
, &guid
);
246 if (!NT_STATUS_IS_OK(status
)) {
249 out
->data
= (uint8_t *)GUID_string(mem_ctx
, &guid
);
250 if (out
->data
== NULL
) {
253 out
->length
= strlen((const char *)out
->data
);
257 static bool ldif_comparision_objectGUID_isString(const struct ldb_val
*v
)
259 if (v
->length
!= 36 && v
->length
!= 38) return false;
261 /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */
265 static int extended_dn_read_GUID(struct ldb_context
*ldb
, void *mem_ctx
,
266 const struct ldb_val
*in
, struct ldb_val
*out
)
269 if (in
->length
== 36 && ldif_read_objectGUID(ldb
, mem_ctx
, in
, out
) == 0) {
273 /* Try as 'hex' form */
274 if (in
->length
!= 32) {
278 *out
= data_blob_talloc(mem_ctx
, NULL
, in
->length
/2+1);
284 (*out
).length
= strhex_to_str((char *)out
->data
, out
->length
,
285 (const char *)in
->data
, in
->length
);
287 /* Check it looks like a GUID */
288 if ((*out
).length
!= 16) {
297 compare two objectGUIDs
299 static int ldif_comparison_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
300 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
302 if (ldif_comparision_objectGUID_isString(v1
) && ldif_comparision_objectGUID_isString(v2
)) {
303 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
304 } else if (ldif_comparision_objectGUID_isString(v1
)
305 && !ldif_comparision_objectGUID_isString(v2
)) {
308 if (ldif_read_objectGUID(ldb
, mem_ctx
, v1
, &v
) != 0) {
309 /* Perhaps it wasn't a valid string after all */
310 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
312 ret
= ldb_comparison_binary(ldb
, mem_ctx
, &v
, v2
);
315 } else if (!ldif_comparision_objectGUID_isString(v1
)
316 && ldif_comparision_objectGUID_isString(v2
)) {
319 if (ldif_read_objectGUID(ldb
, mem_ctx
, v2
, &v
) != 0) {
320 /* Perhaps it wasn't a valid string after all */
321 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
323 ret
= ldb_comparison_binary(ldb
, mem_ctx
, v1
, &v
);
327 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
331 canonicalise a objectGUID
333 static int ldif_canonicalise_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
334 const struct ldb_val
*in
, struct ldb_val
*out
)
336 if (ldif_comparision_objectGUID_isString(in
)) {
337 if (ldif_read_objectGUID(ldb
, mem_ctx
, in
, out
) != 0) {
338 /* Perhaps it wasn't a valid string after all */
339 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
343 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
348 convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob
350 static int ldif_read_ntSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
351 const struct ldb_val
*in
, struct ldb_val
*out
)
353 struct security_descriptor
*sd
;
354 enum ndr_err_code ndr_err
;
356 sd
= talloc(mem_ctx
, struct security_descriptor
);
361 ndr_err
= ndr_pull_struct_blob(in
, sd
, sd
,
362 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
363 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
364 /* If this does not parse, then it is probably SDDL, and we should try it that way */
366 const struct dom_sid
*sid
= samdb_domain_sid(ldb
);
368 sd
= sddl_decode(mem_ctx
, (const char *)in
->data
, sid
);
374 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
, sd
,
375 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
);
377 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
385 convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format)
387 static int ldif_write_ntSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
388 const struct ldb_val
*in
, struct ldb_val
*out
)
390 struct security_descriptor
*sd
;
391 enum ndr_err_code ndr_err
;
393 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
394 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
395 sizeof(struct security_descriptor
),
396 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
,
397 (ndr_print_fn_t
)ndr_print_security_descriptor
,
402 sd
= talloc(mem_ctx
, struct security_descriptor
);
406 /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
407 ndr_err
= ndr_pull_struct_blob(in
, sd
, sd
,
408 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
409 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
413 out
->data
= (uint8_t *)sddl_encode(mem_ctx
, sd
, samdb_domain_sid_cache_only(ldb
));
415 if (out
->data
== NULL
) {
418 out
->length
= strlen((const char *)out
->data
);
423 convert a string formatted SDDL to a ldif formatted ntSecurityDescriptor (SDDL format)
425 static int ldif_write_sddlSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
426 const struct ldb_val
*in
, struct ldb_val
*out
)
428 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
429 struct security_descriptor
*sd
;
430 const struct dom_sid
*sid
= samdb_domain_sid(ldb
);
432 sd
= sddl_decode(mem_ctx
, (const char *)in
->data
, sid
);
433 out
->data
= (uint8_t *)ndr_print_struct_string(mem_ctx
,
434 (ndr_print_fn_t
)ndr_print_security_descriptor
,
436 out
->length
= strlen((const char *)out
->data
);
441 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
445 canonicalise an objectCategory. We use the long form as the canonical form:
446 'person' becomes cn=Person,cn=Schema,cn=Configuration,<basedn>
448 Also any short name of an objectClass that points to a different
449 class (such as user) has the canonical form of the class it's
450 defaultObjectCategory points to (eg
451 cn=Person,cn=Schema,cn=Configuration,<basedn>)
454 static int ldif_canonicalise_objectCategory(struct ldb_context
*ldb
, void *mem_ctx
,
455 const struct ldb_val
*in
, struct ldb_val
*out
)
457 struct ldb_dn
*dn1
= NULL
;
458 const struct dsdb_schema
*schema
= dsdb_get_schema(ldb
, NULL
);
459 const struct dsdb_class
*sclass
;
460 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
462 return LDB_ERR_OPERATIONS_ERROR
;
466 talloc_free(tmp_ctx
);
467 *out
= data_blob_talloc(mem_ctx
, in
->data
, in
->length
);
468 if (in
->data
&& !out
->data
) {
469 return LDB_ERR_OPERATIONS_ERROR
;
473 dn1
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, in
);
474 if ( ! ldb_dn_validate(dn1
)) {
475 const char *lDAPDisplayName
= talloc_strndup(tmp_ctx
, (char *)in
->data
, in
->length
);
476 sclass
= dsdb_class_by_lDAPDisplayName(schema
, lDAPDisplayName
);
478 struct ldb_dn
*dn
= ldb_dn_new(tmp_ctx
, ldb
,
479 sclass
->defaultObjectCategory
);
481 talloc_free(tmp_ctx
);
482 return LDB_ERR_OPERATIONS_ERROR
;
485 *out
= data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx
, dn
));
486 talloc_free(tmp_ctx
);
489 return LDB_ERR_OPERATIONS_ERROR
;
493 *out
= data_blob_talloc(mem_ctx
, in
->data
, in
->length
);
494 talloc_free(tmp_ctx
);
496 if (in
->data
&& !out
->data
) {
497 return LDB_ERR_OPERATIONS_ERROR
;
502 *out
= data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx
, dn1
));
503 talloc_free(tmp_ctx
);
506 return LDB_ERR_OPERATIONS_ERROR
;
511 static int ldif_comparison_objectCategory(struct ldb_context
*ldb
, void *mem_ctx
,
512 const struct ldb_val
*v1
,
513 const struct ldb_val
*v2
)
515 return ldb_any_comparison(ldb
, mem_ctx
, ldif_canonicalise_objectCategory
,
520 convert a NDR formatted blob to a ldif formatted schemaInfo
522 static int ldif_write_schemaInfo(struct ldb_context
*ldb
, void *mem_ctx
,
523 const struct ldb_val
*in
, struct ldb_val
*out
)
525 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
526 sizeof(struct repsFromToBlob
),
527 (ndr_pull_flags_fn_t
)ndr_pull_schemaInfoBlob
,
528 (ndr_print_fn_t
)ndr_print_schemaInfoBlob
,
533 convert a ldif formatted prefixMap to a NDR formatted blob
535 static int ldif_read_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
536 const struct ldb_val
*in
, struct ldb_val
*out
)
538 struct prefixMapBlob
*blob
;
539 enum ndr_err_code ndr_err
;
540 char *string
, *line
, *p
, *oid
;
543 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
545 if (tmp_ctx
== NULL
) {
549 blob
= talloc_zero(tmp_ctx
, struct prefixMapBlob
);
551 talloc_free(tmp_ctx
);
555 /* use the switch value to detect if this is in the binary
558 if (in
->length
>= 4 && IVAL(in
->data
, 0) == PREFIX_MAP_VERSION_DSDB
) {
559 ndr_err
= ndr_pull_struct_blob(in
, tmp_ctx
, blob
,
560 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
);
561 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
562 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
,
564 (ndr_push_flags_fn_t
)ndr_push_prefixMapBlob
);
565 talloc_free(tmp_ctx
);
566 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
573 /* If this does not parse, then it is probably the text version, and we should try it that way */
574 blob
->version
= PREFIX_MAP_VERSION_DSDB
;
576 string
= talloc_strndup(mem_ctx
, (const char *)in
->data
, in
->length
);
577 if (string
== NULL
) {
583 while (line
&& line
[0]) {
588 p
=strchr(line
, '\n');
593 /* allow a trailing separator */
598 blob
->ctr
.dsdb
.mappings
= talloc_realloc(blob
,
599 blob
->ctr
.dsdb
.mappings
,
600 struct drsuapi_DsReplicaOIDMapping
,
601 blob
->ctr
.dsdb
.num_mappings
+1);
602 if (!blob
->ctr
.dsdb
.mappings
) {
603 talloc_free(tmp_ctx
);
607 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].id_prefix
= strtoul(line
, &oid
, 10);
610 talloc_free(tmp_ctx
);
614 /* we know there must be at least ":" */
617 if (!ber_write_partial_OID_String(blob
->ctr
.dsdb
.mappings
, &oid_blob
, oid
)) {
618 talloc_free(tmp_ctx
);
621 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].oid
.length
= oid_blob
.length
;
622 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].oid
.binary_oid
= oid_blob
.data
;
624 blob
->ctr
.dsdb
.num_mappings
++;
626 /* Now look past the terminator we added above */
634 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
,
636 (ndr_push_flags_fn_t
)ndr_push_prefixMapBlob
);
637 talloc_free(tmp_ctx
);
638 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
645 convert a NDR formatted blob to a ldif formatted prefixMap
647 static int ldif_write_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
648 const struct ldb_val
*in
, struct ldb_val
*out
)
650 struct prefixMapBlob
*blob
;
651 enum ndr_err_code ndr_err
;
655 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
657 /* try to decode the blob as S4 prefixMap */
658 err
= ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
659 sizeof(struct prefixMapBlob
),
660 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
,
661 (ndr_print_fn_t
)ndr_print_prefixMapBlob
,
666 /* try parsing it as Windows PrefixMap value */
667 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
668 sizeof(struct drsuapi_MSPrefixMap_Ctr
),
669 (ndr_pull_flags_fn_t
)ndr_pull_drsuapi_MSPrefixMap_Ctr
,
670 (ndr_print_fn_t
)ndr_print_drsuapi_MSPrefixMap_Ctr
,
674 blob
= talloc(mem_ctx
, struct prefixMapBlob
);
678 ndr_err
= ndr_pull_struct_blob_all(in
, blob
,
680 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
);
681 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
684 if (blob
->version
!= PREFIX_MAP_VERSION_DSDB
) {
687 string
= talloc_strdup(mem_ctx
, "");
688 if (string
== NULL
) {
692 for (i
=0; i
< blob
->ctr
.dsdb
.num_mappings
; i
++) {
694 char *partial_oid
= NULL
;
697 string
= talloc_asprintf_append(string
, ";");
700 oid_blob
= data_blob_const(blob
->ctr
.dsdb
.mappings
[i
].oid
.binary_oid
,
701 blob
->ctr
.dsdb
.mappings
[i
].oid
.length
);
702 if (!ber_read_partial_OID_String(blob
, oid_blob
, &partial_oid
)) {
703 DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X",
704 blob
->ctr
.dsdb
.mappings
[i
].id_prefix
));
707 string
= talloc_asprintf_append(string
, "%u:%s",
708 blob
->ctr
.dsdb
.mappings
[i
].id_prefix
,
710 talloc_free(discard_const(partial_oid
));
711 if (string
== NULL
) {
717 *out
= data_blob_string_const(string
);
725 static bool ldif_comparision_prefixMap_isString(const struct ldb_val
*v
)
731 if (IVAL(v
->data
, 0) == PREFIX_MAP_VERSION_DSDB
) {
739 canonicalise a prefixMap
741 static int ldif_canonicalise_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
742 const struct ldb_val
*in
, struct ldb_val
*out
)
744 if (ldif_comparision_prefixMap_isString(in
)) {
745 return ldif_read_prefixMap(ldb
, mem_ctx
, in
, out
);
747 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
750 static int ldif_comparison_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
751 const struct ldb_val
*v1
,
752 const struct ldb_val
*v2
)
754 return ldb_any_comparison(ldb
, mem_ctx
, ldif_canonicalise_prefixMap
,
758 /* length limited conversion of a ldb_val to a int32_t */
759 static int val_to_int32(const struct ldb_val
*in
, int32_t *v
)
764 /* make sure we don't read past the end of the data */
765 if (in
->length
> sizeof(buf
)-1) {
766 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
768 strncpy(buf
, (char *)in
->data
, in
->length
);
771 /* We've to use "strtoll" here to have the intended overflows.
772 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
773 *v
= (int32_t) strtoll(buf
, &end
, 0);
775 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
780 /* length limited conversion of a ldb_val to a int64_t */
781 static int val_to_int64(const struct ldb_val
*in
, int64_t *v
)
786 /* make sure we don't read past the end of the data */
787 if (in
->length
> sizeof(buf
)-1) {
788 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
790 strncpy(buf
, (char *)in
->data
, in
->length
);
793 *v
= (int64_t) strtoll(buf
, &end
, 0);
795 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
800 /* Canonicalisation of two 32-bit integers */
801 static int ldif_canonicalise_int32(struct ldb_context
*ldb
, void *mem_ctx
,
802 const struct ldb_val
*in
, struct ldb_val
*out
)
807 ret
= val_to_int32(in
, &i
);
808 if (ret
!= LDB_SUCCESS
) {
811 out
->data
= (uint8_t *) talloc_asprintf(mem_ctx
, "%d", i
);
812 if (out
->data
== NULL
) {
814 return LDB_ERR_OPERATIONS_ERROR
;
816 out
->length
= strlen((char *)out
->data
);
820 /* Comparison of two 32-bit integers */
821 static int ldif_comparison_int32(struct ldb_context
*ldb
, void *mem_ctx
,
822 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
825 val_to_int32(v1
, &i1
);
826 val_to_int32(v2
, &i2
);
827 if (i1
== i2
) return 0;
828 return i1
> i2
? 1 : -1;
831 /* Canonicalisation of two 64-bit integers */
832 static int ldif_canonicalise_int64(struct ldb_context
*ldb
, void *mem_ctx
,
833 const struct ldb_val
*in
, struct ldb_val
*out
)
838 ret
= val_to_int64(in
, &i
);
839 if (ret
!= LDB_SUCCESS
) {
842 out
->data
= (uint8_t *) talloc_asprintf(mem_ctx
, "%lld", (long long)i
);
843 if (out
->data
== NULL
) {
845 return LDB_ERR_OPERATIONS_ERROR
;
847 out
->length
= strlen((char *)out
->data
);
851 /* Comparison of two 64-bit integers */
852 static int ldif_comparison_int64(struct ldb_context
*ldb
, void *mem_ctx
,
853 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
856 val_to_int64(v1
, &i1
);
857 val_to_int64(v2
, &i2
);
858 if (i1
== i2
) return 0;
859 return i1
> i2
? 1 : -1;
863 convert a NDR formatted blob to a ldif formatted repsFromTo
865 static int ldif_write_repsFromTo(struct ldb_context
*ldb
, void *mem_ctx
,
866 const struct ldb_val
*in
, struct ldb_val
*out
)
868 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
869 sizeof(struct repsFromToBlob
),
870 (ndr_pull_flags_fn_t
)ndr_pull_repsFromToBlob
,
871 (ndr_print_fn_t
)ndr_print_repsFromToBlob
,
876 convert a NDR formatted blob to a ldif formatted replPropertyMetaData
878 static int ldif_write_replPropertyMetaData(struct ldb_context
*ldb
, void *mem_ctx
,
879 const struct ldb_val
*in
, struct ldb_val
*out
)
881 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
882 sizeof(struct replPropertyMetaDataBlob
),
883 (ndr_pull_flags_fn_t
)ndr_pull_replPropertyMetaDataBlob
,
884 (ndr_print_fn_t
)ndr_print_replPropertyMetaDataBlob
,
889 convert a NDR formatted blob to a ldif formatted replUpToDateVector
891 static int ldif_write_replUpToDateVector(struct ldb_context
*ldb
, void *mem_ctx
,
892 const struct ldb_val
*in
, struct ldb_val
*out
)
894 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
895 sizeof(struct replUpToDateVectorBlob
),
896 (ndr_pull_flags_fn_t
)ndr_pull_replUpToDateVectorBlob
,
897 (ndr_print_fn_t
)ndr_print_replUpToDateVectorBlob
,
901 static int ldif_write_dn_binary_NDR(struct ldb_context
*ldb
, void *mem_ctx
,
902 const struct ldb_val
*in
, struct ldb_val
*out
,
904 ndr_pull_flags_fn_t pull_fn
,
905 ndr_print_fn_t print_fn
,
909 enum ndr_err_code err
;
910 struct dsdb_dn
*dsdb_dn
= NULL
;
914 if (!(ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
)) {
915 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
918 dsdb_dn
= dsdb_dn_parse(mem_ctx
, ldb
, in
, DSDB_SYNTAX_BINARY_DN
);
919 if (dsdb_dn
== NULL
) {
920 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
923 p
= talloc_size(dsdb_dn
, struct_size
);
925 TALLOC_FREE(dsdb_dn
);
926 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
929 err
= ndr_pull_struct_blob(&dsdb_dn
->extra_part
, p
, p
, pull_fn
);
930 if (err
!= NDR_ERR_SUCCESS
) {
931 /* fail in not in mask_error mode */
935 TALLOC_FREE(dsdb_dn
);
936 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
939 dn_str
= ldb_dn_get_extended_linearized(dsdb_dn
, dsdb_dn
->dn
, 1);
940 if (dn_str
== NULL
) {
941 TALLOC_FREE(dsdb_dn
);
942 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
945 str
= ndr_print_struct_string(mem_ctx
, print_fn
, dn_str
, p
);
946 TALLOC_FREE(dsdb_dn
);
948 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
951 *out
= data_blob_string_const(str
);
955 static int ldif_write_msDS_RevealedUsers(struct ldb_context
*ldb
, void *mem_ctx
,
956 const struct ldb_val
*in
, struct ldb_val
*out
)
958 return ldif_write_dn_binary_NDR(ldb
, mem_ctx
, in
, out
,
959 sizeof(struct replPropertyMetaData1
),
960 (ndr_pull_flags_fn_t
)ndr_pull_replPropertyMetaData1
,
961 (ndr_print_fn_t
)ndr_print_replPropertyMetaData1
,
966 convert a NDR formatted blob to a ldif formatted dnsRecord
968 static int ldif_write_dnsRecord(struct ldb_context
*ldb
, void *mem_ctx
,
969 const struct ldb_val
*in
, struct ldb_val
*out
)
971 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
972 sizeof(struct dnsp_DnssrvRpcRecord
),
973 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
,
974 (ndr_print_fn_t
)ndr_print_dnsp_DnssrvRpcRecord
,
979 convert a NDR formatted blob to a ldif formatted dnsProperty
981 static int ldif_write_dnsProperty(struct ldb_context
*ldb
, void *mem_ctx
,
982 const struct ldb_val
*in
, struct ldb_val
*out
)
984 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
985 sizeof(struct dnsp_DnsProperty
),
986 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnsProperty
,
987 (ndr_print_fn_t
)ndr_print_dnsp_DnsProperty
,
992 convert a NDR formatted blob of a supplementalCredentials into text
994 static int ldif_write_supplementalCredentialsBlob(struct ldb_context
*ldb
, void *mem_ctx
,
995 const struct ldb_val
*in
, struct ldb_val
*out
)
997 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
998 sizeof(struct supplementalCredentialsBlob
),
999 (ndr_pull_flags_fn_t
)ndr_pull_supplementalCredentialsBlob
,
1000 (ndr_print_fn_t
)ndr_print_supplementalCredentialsBlob
,
1005 convert a NDR formatted blob to a ldif formatted trustAuthInOutBlob
1007 static int ldif_write_trustAuthInOutBlob(struct ldb_context
*ldb
, void *mem_ctx
,
1008 const struct ldb_val
*in
, struct ldb_val
*out
)
1010 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1011 sizeof(struct trustAuthInOutBlob
),
1012 (ndr_pull_flags_fn_t
)ndr_pull_trustAuthInOutBlob
,
1013 (ndr_print_fn_t
)ndr_print_trustAuthInOutBlob
,
1018 convert a NDR formatted blob to a ldif formatted msDS-TrustForestTrustInfo
1020 static int ldif_write_ForestTrustInfo(struct ldb_context
*ldb
, void *mem_ctx
,
1021 const struct ldb_val
*in
, struct ldb_val
*out
)
1023 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1024 sizeof(struct ForestTrustInfo
),
1025 (ndr_pull_flags_fn_t
)ndr_pull_ForestTrustInfo
,
1026 (ndr_print_fn_t
)ndr_print_ForestTrustInfo
,
1030 convert a NDR formatted blob of a partialAttributeSet into text
1032 static int ldif_write_partialAttributeSet(struct ldb_context
*ldb
, void *mem_ctx
,
1033 const struct ldb_val
*in
, struct ldb_val
*out
)
1035 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1036 sizeof(struct partialAttributeSetBlob
),
1037 (ndr_pull_flags_fn_t
)ndr_pull_partialAttributeSetBlob
,
1038 (ndr_print_fn_t
)ndr_print_partialAttributeSetBlob
,
1043 static int extended_dn_write_hex(struct ldb_context
*ldb
, void *mem_ctx
,
1044 const struct ldb_val
*in
, struct ldb_val
*out
)
1046 *out
= data_blob_string_const(data_blob_hex_string_lower(mem_ctx
, in
));
1056 static int samba_ldb_dn_link_comparison(struct ldb_context
*ldb
, void *mem_ctx
,
1057 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
1059 struct ldb_dn
*dn1
= NULL
, *dn2
= NULL
;
1062 if (dsdb_dn_is_deleted_val(v1
)) {
1063 /* If the DN is deleted, then we can't search for it */
1067 if (dsdb_dn_is_deleted_val(v2
)) {
1068 /* If the DN is deleted, then we can't search for it */
1072 dn1
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, v1
);
1073 if ( ! ldb_dn_validate(dn1
)) return -1;
1075 dn2
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, v2
);
1076 if ( ! ldb_dn_validate(dn2
)) {
1081 ret
= ldb_dn_compare(dn1
, dn2
);
1088 static int samba_ldb_dn_link_canonicalise(struct ldb_context
*ldb
, void *mem_ctx
,
1089 const struct ldb_val
*in
, struct ldb_val
*out
)
1097 dn
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, in
);
1098 if ( ! ldb_dn_validate(dn
)) {
1099 return LDB_ERR_INVALID_DN_SYNTAX
;
1102 /* By including the RMD_FLAGS of a deleted DN, we ensure it
1103 * does not casually match a not deleted DN */
1104 if (dsdb_dn_is_deleted_val(in
)) {
1105 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
,
1107 dsdb_dn_val_rmd_flags(in
),
1108 ldb_dn_get_casefold(dn
));
1110 out
->data
= (uint8_t *)ldb_dn_alloc_casefold(mem_ctx
, dn
);
1113 if (out
->data
== NULL
) {
1116 out
->length
= strlen((char *)out
->data
);
1128 write a 64 bit 2-part range
1130 static int ldif_write_range64(struct ldb_context
*ldb
, void *mem_ctx
,
1131 const struct ldb_val
*in
, struct ldb_val
*out
)
1135 ret
= val_to_int64(in
, &v
);
1136 if (ret
!= LDB_SUCCESS
) {
1139 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
, "%lu-%lu",
1140 (unsigned long)(v
&0xFFFFFFFF),
1141 (unsigned long)(v
>>32));
1142 if (out
->data
== NULL
) {
1144 return LDB_ERR_OPERATIONS_ERROR
;
1146 out
->length
= strlen((char *)out
->data
);
1151 read a 64 bit 2-part range
1153 static int ldif_read_range64(struct ldb_context
*ldb
, void *mem_ctx
,
1154 const struct ldb_val
*in
, struct ldb_val
*out
)
1156 unsigned long high
, low
;
1159 if (memchr(in
->data
, '-', in
->length
) == NULL
) {
1160 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1163 if (in
->length
> sizeof(buf
)-1) {
1164 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
1166 strncpy(buf
, (const char *)in
->data
, in
->length
);
1167 buf
[in
->length
] = 0;
1169 if (sscanf(buf
, "%lu-%lu", &low
, &high
) != 2) {
1170 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
1173 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
, "%llu",
1174 (unsigned long long)(((uint64_t)high
)<<32) | (low
));
1176 if (out
->data
== NULL
) {
1178 return LDB_ERR_OPERATIONS_ERROR
;
1180 out
->length
= strlen((char *)out
->data
);
1185 when this operator_fn is set for a syntax, the backend calls is in
1186 preference to the comparison function. We are told the exact
1187 comparison operation that is needed, and we can return errors
1189 static int samba_syntax_operator_fn(struct ldb_context
*ldb
, enum ldb_parse_op operation
,
1190 const struct ldb_schema_attribute
*a
,
1191 const struct ldb_val
*v1
, const struct ldb_val
*v2
, bool *matched
)
1193 switch (operation
) {
1197 case LDB_OP_SUBSTRING
:
1199 case LDB_OP_EXTENDED
:
1200 /* handled in the backends */
1201 return LDB_ERR_INAPPROPRIATE_MATCHING
;
1203 case LDB_OP_GREATER
:
1205 case LDB_OP_EQUALITY
:
1207 TALLOC_CTX
*tmp_ctx
= talloc_new(ldb
);
1209 if (tmp_ctx
== NULL
) {
1210 return ldb_oom(ldb
);
1212 ret
= a
->syntax
->comparison_fn(ldb
, tmp_ctx
, v1
, v2
);
1213 talloc_free(tmp_ctx
);
1214 if (operation
== LDB_OP_GREATER
) {
1215 *matched
= (ret
>= 0);
1216 } else if (operation
== LDB_OP_LESS
) {
1217 *matched
= (ret
<= 0);
1219 *matched
= (ret
== 0);
1224 case LDB_OP_PRESENT
:
1229 /* we shouldn't get here */
1230 return LDB_ERR_INAPPROPRIATE_MATCHING
;
1234 compare two binary objects. This is correct for sorting as the sort order is:
1241 rather than ldb_comparison_binary() which is:
1249 static int samba_ldb_comparison_binary(struct ldb_context
*ldb
, void *mem_ctx
,
1250 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
1252 return data_blob_cmp(v1
, v2
);
1256 when this operator_fn is set for a syntax, the backend calls is in
1257 preference to the comparison function. We are told the exact
1258 comparison operation that is needed, and we can return errors.
1260 This mode optimises for ldb_comparison_binary() if we need equality,
1261 as this should be faster as it can do a length-check first.
1263 static int samba_syntax_binary_operator_fn(struct ldb_context
*ldb
, enum ldb_parse_op operation
,
1264 const struct ldb_schema_attribute
*a
,
1265 const struct ldb_val
*v1
, const struct ldb_val
*v2
, bool *matched
)
1267 if (operation
== LDB_OP_EQUALITY
) {
1268 *matched
= (ldb_comparison_binary(ldb
, NULL
, v1
, v2
) == 0);
1271 return samba_syntax_operator_fn(ldb
, operation
, a
, v1
, v2
, matched
);
1275 see if two DNs match, comparing first by GUID, then by SID, and
1276 finally by string components
1278 static int samba_dn_extended_match(struct ldb_context
*ldb
,
1279 const struct ldb_val
*v1
,
1280 const struct ldb_val
*v2
,
1283 TALLOC_CTX
*tmp_ctx
;
1284 struct ldb_dn
*dn1
, *dn2
;
1285 const struct ldb_val
*guid1
, *guid2
, *sid1
, *sid2
;
1286 uint32_t rmd_flags1
, rmd_flags2
;
1288 tmp_ctx
= talloc_new(ldb
);
1290 dn1
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, v1
);
1291 dn2
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, v2
);
1293 /* couldn't parse as DN's */
1294 talloc_free(tmp_ctx
);
1299 rmd_flags1
= dsdb_dn_rmd_flags(dn1
);
1300 rmd_flags2
= dsdb_dn_rmd_flags(dn2
);
1302 if ((rmd_flags1
& DSDB_RMD_FLAG_DELETED
) !=
1303 (rmd_flags2
& DSDB_RMD_FLAG_DELETED
)) {
1304 /* only match if they have the same deletion status */
1305 talloc_free(tmp_ctx
);
1311 guid1
= ldb_dn_get_extended_component(dn1
, "GUID");
1312 guid2
= ldb_dn_get_extended_component(dn2
, "GUID");
1313 if (guid1
&& guid2
) {
1314 (*matched
) = (data_blob_cmp(guid1
, guid2
) == 0);
1315 talloc_free(tmp_ctx
);
1319 sid1
= ldb_dn_get_extended_component(dn1
, "SID");
1320 sid2
= ldb_dn_get_extended_component(dn2
, "SID");
1322 (*matched
) = (data_blob_cmp(sid1
, sid2
) == 0);
1323 talloc_free(tmp_ctx
);
1327 (*matched
) = (ldb_dn_compare(dn1
, dn2
) == 0);
1329 talloc_free(tmp_ctx
);
1334 special operation for DNs, to take account of the RMD_FLAGS deleted bit
1336 static int samba_syntax_operator_dn(struct ldb_context
*ldb
, enum ldb_parse_op operation
,
1337 const struct ldb_schema_attribute
*a
,
1338 const struct ldb_val
*v1
, const struct ldb_val
*v2
, bool *matched
)
1340 if (operation
== LDB_OP_PRESENT
&& dsdb_dn_is_deleted_val(v1
)) {
1341 /* If the DN is deleted, then we can't search for it */
1343 /* should this be for equality too? */
1348 if (operation
== LDB_OP_EQUALITY
&&
1349 samba_dn_extended_match(ldb
, v1
, v2
, matched
) == LDB_SUCCESS
) {
1353 return samba_syntax_operator_fn(ldb
, operation
, a
, v1
, v2
, matched
);
1357 static const struct ldb_schema_syntax samba_syntaxes
[] = {
1359 .name
= LDB_SYNTAX_SAMBA_SID
,
1360 .ldif_read_fn
= ldif_read_objectSid
,
1361 .ldif_write_fn
= ldif_write_objectSid
,
1362 .canonicalise_fn
= ldif_canonicalise_objectSid
,
1363 .comparison_fn
= ldif_comparison_objectSid
,
1364 .operator_fn
= samba_syntax_operator_fn
1366 .name
= LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR
,
1367 .ldif_read_fn
= ldif_read_ntSecurityDescriptor
,
1368 .ldif_write_fn
= ldif_write_ntSecurityDescriptor
,
1369 .canonicalise_fn
= ldb_handler_copy
,
1370 .comparison_fn
= samba_ldb_comparison_binary
,
1371 .operator_fn
= samba_syntax_binary_operator_fn
1373 .name
= LDB_SYNTAX_SAMBA_SDDL_SECURITY_DESCRIPTOR
,
1374 .ldif_read_fn
= ldb_handler_copy
,
1375 .ldif_write_fn
= ldif_write_sddlSecurityDescriptor
,
1376 .canonicalise_fn
= ldb_handler_fold
,
1377 .comparison_fn
= ldb_comparison_fold
,
1378 .operator_fn
= samba_syntax_operator_fn
1380 .name
= LDB_SYNTAX_SAMBA_GUID
,
1381 .ldif_read_fn
= ldif_read_objectGUID
,
1382 .ldif_write_fn
= ldif_write_objectGUID
,
1383 .canonicalise_fn
= ldif_canonicalise_objectGUID
,
1384 .comparison_fn
= ldif_comparison_objectGUID
,
1385 .operator_fn
= samba_syntax_operator_fn
1387 .name
= LDB_SYNTAX_SAMBA_OBJECT_CATEGORY
,
1388 .ldif_read_fn
= ldb_handler_copy
,
1389 .ldif_write_fn
= ldb_handler_copy
,
1390 .canonicalise_fn
= ldif_canonicalise_objectCategory
,
1391 .comparison_fn
= ldif_comparison_objectCategory
,
1392 .operator_fn
= samba_syntax_operator_fn
1394 .name
= LDB_SYNTAX_SAMBA_SCHEMAINFO
,
1395 .ldif_read_fn
= ldb_handler_copy
,
1396 .ldif_write_fn
= ldif_write_schemaInfo
,
1397 .canonicalise_fn
= ldb_handler_copy
,
1398 .comparison_fn
= samba_ldb_comparison_binary
,
1399 .operator_fn
= samba_syntax_binary_operator_fn
1401 .name
= LDB_SYNTAX_SAMBA_PREFIX_MAP
,
1402 .ldif_read_fn
= ldif_read_prefixMap
,
1403 .ldif_write_fn
= ldif_write_prefixMap
,
1404 .canonicalise_fn
= ldif_canonicalise_prefixMap
,
1405 .comparison_fn
= ldif_comparison_prefixMap
,
1406 .operator_fn
= samba_syntax_operator_fn
1408 .name
= LDB_SYNTAX_SAMBA_INT32
,
1409 .ldif_read_fn
= ldb_handler_copy
,
1410 .ldif_write_fn
= ldb_handler_copy
,
1411 .canonicalise_fn
= ldif_canonicalise_int32
,
1412 .comparison_fn
= ldif_comparison_int32
,
1413 .operator_fn
= samba_syntax_operator_fn
1415 .name
= LDB_SYNTAX_SAMBA_REPSFROMTO
,
1416 .ldif_read_fn
= ldb_handler_copy
,
1417 .ldif_write_fn
= ldif_write_repsFromTo
,
1418 .canonicalise_fn
= ldb_handler_copy
,
1419 .comparison_fn
= samba_ldb_comparison_binary
,
1420 .operator_fn
= samba_syntax_binary_operator_fn
1422 .name
= LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA
,
1423 .ldif_read_fn
= ldb_handler_copy
,
1424 .ldif_write_fn
= ldif_write_replPropertyMetaData
,
1425 .canonicalise_fn
= ldb_handler_copy
,
1426 .comparison_fn
= samba_ldb_comparison_binary
,
1427 .operator_fn
= samba_syntax_binary_operator_fn
1429 .name
= LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR
,
1430 .ldif_read_fn
= ldb_handler_copy
,
1431 .ldif_write_fn
= ldif_write_replUpToDateVector
,
1432 .canonicalise_fn
= ldb_handler_copy
,
1433 .comparison_fn
= samba_ldb_comparison_binary
,
1434 .operator_fn
= samba_syntax_binary_operator_fn
1436 .name
= LDB_SYNTAX_SAMBA_REVEALEDUSERS
,
1437 .ldif_read_fn
= ldb_handler_copy
,
1438 .ldif_write_fn
= ldif_write_msDS_RevealedUsers
,
1439 .canonicalise_fn
= dsdb_dn_binary_canonicalise
,
1440 .comparison_fn
= dsdb_dn_binary_comparison
,
1441 .operator_fn
= samba_syntax_operator_fn
1443 .name
= LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
,
1444 .ldif_read_fn
= ldb_handler_copy
,
1445 .ldif_write_fn
= ldif_write_trustAuthInOutBlob
,
1446 .canonicalise_fn
= ldb_handler_copy
,
1447 .comparison_fn
= samba_ldb_comparison_binary
,
1448 .operator_fn
= samba_syntax_binary_operator_fn
1450 .name
= LDB_SYNTAX_SAMBA_FORESTTRUSTINFO
,
1451 .ldif_read_fn
= ldb_handler_copy
,
1452 .ldif_write_fn
= ldif_write_ForestTrustInfo
,
1453 .canonicalise_fn
= ldb_handler_copy
,
1454 .comparison_fn
= samba_ldb_comparison_binary
,
1455 .operator_fn
= samba_syntax_binary_operator_fn
1457 .name
= DSDB_SYNTAX_BINARY_DN
,
1458 .ldif_read_fn
= ldb_handler_copy
,
1459 .ldif_write_fn
= ldb_handler_copy
,
1460 .canonicalise_fn
= dsdb_dn_binary_canonicalise
,
1461 .comparison_fn
= dsdb_dn_binary_comparison
,
1462 .operator_fn
= samba_syntax_operator_fn
1464 .name
= DSDB_SYNTAX_STRING_DN
,
1465 .ldif_read_fn
= ldb_handler_copy
,
1466 .ldif_write_fn
= ldb_handler_copy
,
1467 .canonicalise_fn
= dsdb_dn_string_canonicalise
,
1468 .comparison_fn
= dsdb_dn_string_comparison
,
1469 .operator_fn
= samba_syntax_operator_fn
1471 .name
= LDB_SYNTAX_DN
,
1472 .ldif_read_fn
= ldb_handler_copy
,
1473 .ldif_write_fn
= ldb_handler_copy
,
1474 .canonicalise_fn
= samba_ldb_dn_link_canonicalise
,
1475 .comparison_fn
= samba_ldb_dn_link_comparison
,
1476 .operator_fn
= samba_syntax_operator_dn
1478 .name
= LDB_SYNTAX_SAMBA_RANGE64
,
1479 .ldif_read_fn
= ldif_read_range64
,
1480 .ldif_write_fn
= ldif_write_range64
,
1481 .canonicalise_fn
= ldif_canonicalise_int64
,
1482 .comparison_fn
= ldif_comparison_int64
,
1483 .operator_fn
= samba_syntax_operator_fn
1485 .name
= LDB_SYNTAX_SAMBA_DNSRECORD
,
1486 .ldif_read_fn
= ldb_handler_copy
,
1487 .ldif_write_fn
= ldif_write_dnsRecord
,
1488 .canonicalise_fn
= ldb_handler_copy
,
1489 .comparison_fn
= samba_ldb_comparison_binary
,
1490 .operator_fn
= samba_syntax_binary_operator_fn
1492 .name
= LDB_SYNTAX_SAMBA_DNSPROPERTY
,
1493 .ldif_read_fn
= ldb_handler_copy
,
1494 .ldif_write_fn
= ldif_write_dnsProperty
,
1495 .canonicalise_fn
= ldb_handler_copy
,
1496 .comparison_fn
= samba_ldb_comparison_binary
,
1497 .operator_fn
= samba_syntax_binary_operator_fn
1499 .name
= LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS
,
1500 .ldif_read_fn
= ldb_handler_copy
,
1501 .ldif_write_fn
= ldif_write_supplementalCredentialsBlob
,
1502 .canonicalise_fn
= ldb_handler_copy
,
1503 .comparison_fn
= samba_ldb_comparison_binary
,
1504 .operator_fn
= samba_syntax_binary_operator_fn
1506 .name
= LDB_SYNTAX_SAMBA_PARTIALATTRIBUTESET
,
1507 .ldif_read_fn
= ldb_handler_copy
,
1508 .ldif_write_fn
= ldif_write_partialAttributeSet
,
1509 .canonicalise_fn
= ldb_handler_copy
,
1510 .comparison_fn
= samba_ldb_comparison_binary
,
1511 .operator_fn
= samba_syntax_binary_operator_fn
1513 .name
= LDB_SYNTAX_SAMBA_OCTET_STRING
,
1514 .ldif_read_fn
= ldb_handler_copy
,
1515 .ldif_write_fn
= ldb_handler_copy
,
1516 .canonicalise_fn
= ldb_handler_copy
,
1517 .comparison_fn
= samba_ldb_comparison_binary
,
1518 .operator_fn
= samba_syntax_binary_operator_fn
1522 static const struct ldb_dn_extended_syntax samba_dn_syntax
[] = {
1525 .read_fn
= extended_dn_read_SID
,
1526 .write_clear_fn
= ldif_write_objectSid
,
1527 .write_hex_fn
= extended_dn_write_hex
1530 .read_fn
= extended_dn_read_GUID
,
1531 .write_clear_fn
= ldif_write_objectGUID
,
1532 .write_hex_fn
= extended_dn_write_hex
1535 .read_fn
= ldb_handler_copy
,
1536 .write_clear_fn
= ldb_handler_copy
,
1537 .write_hex_fn
= ldb_handler_copy
1539 .name
= "RMD_INVOCID",
1540 .read_fn
= extended_dn_read_GUID
,
1541 .write_clear_fn
= ldif_write_objectGUID
,
1542 .write_hex_fn
= extended_dn_write_hex
1544 .name
= "RMD_FLAGS",
1545 .read_fn
= ldb_handler_copy
,
1546 .write_clear_fn
= ldb_handler_copy
,
1547 .write_hex_fn
= ldb_handler_copy
1549 .name
= "RMD_ADDTIME",
1550 .read_fn
= ldb_handler_copy
,
1551 .write_clear_fn
= ldb_handler_copy
,
1552 .write_hex_fn
= ldb_handler_copy
1554 .name
= "RMD_CHANGETIME",
1555 .read_fn
= ldb_handler_copy
,
1556 .write_clear_fn
= ldb_handler_copy
,
1557 .write_hex_fn
= ldb_handler_copy
1559 .name
= "RMD_LOCAL_USN",
1560 .read_fn
= ldb_handler_copy
,
1561 .write_clear_fn
= ldb_handler_copy
,
1562 .write_hex_fn
= ldb_handler_copy
1564 .name
= "RMD_ORIGINATING_USN",
1565 .read_fn
= ldb_handler_copy
,
1566 .write_clear_fn
= ldb_handler_copy
,
1567 .write_hex_fn
= ldb_handler_copy
1569 .name
= "RMD_VERSION",
1570 .read_fn
= ldb_handler_copy
,
1571 .write_clear_fn
= ldb_handler_copy
,
1572 .write_hex_fn
= ldb_handler_copy
1576 /* TODO: Should be dynamic at some point */
1577 static const struct {
1580 } samba_attributes
[] = {
1581 { "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR
},
1582 { "oMSyntax", LDB_SYNTAX_SAMBA_INT32
},
1583 { "objectCategory", LDB_SYNTAX_SAMBA_OBJECT_CATEGORY
},
1584 { "schemaInfo", LDB_SYNTAX_SAMBA_SCHEMAINFO
},
1585 { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP
},
1586 { "repsFrom", LDB_SYNTAX_SAMBA_REPSFROMTO
},
1587 { "repsTo", LDB_SYNTAX_SAMBA_REPSFROMTO
},
1588 { "replPropertyMetaData", LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA
},
1589 { "replUpToDateVector", LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR
},
1590 { "msDS-RevealedUsers", LDB_SYNTAX_SAMBA_REVEALEDUSERS
},
1591 { "trustAuthIncoming", LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
},
1592 { "trustAuthOutgoing", LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
},
1593 { "msDS-TrustForestTrustInfo", LDB_SYNTAX_SAMBA_FORESTTRUSTINFO
},
1594 { "rIDAllocationPool", LDB_SYNTAX_SAMBA_RANGE64
},
1595 { "rIDPreviousAllocationPool", LDB_SYNTAX_SAMBA_RANGE64
},
1596 { "rIDAvailablePool", LDB_SYNTAX_SAMBA_RANGE64
},
1597 { "defaultSecurityDescriptor", LDB_SYNTAX_SAMBA_SDDL_SECURITY_DESCRIPTOR
},
1600 * these are extracted by searching
1601 * (&(attributeSyntax=2.5.5.17)(omSyntax=4))
1603 * Except: msAuthz-CentralAccessPolicyID as it might be a GUID see:
1604 * adminDescription: For a Central Access Policy, this attribute defines a GUID t
1605 * hat can be used to identify the set of policies when applied to a resource.
1606 * Until we see a msAuthz-CentralAccessPolicyID value on a windows
1607 * server, we ignore it here.
1609 { "mS-DS-CreatorSID", LDB_SYNTAX_SAMBA_SID
},
1610 { "msDS-QuotaTrustee", LDB_SYNTAX_SAMBA_SID
},
1611 { "objectSid", LDB_SYNTAX_SAMBA_SID
},
1612 { "tokenGroups", LDB_SYNTAX_SAMBA_SID
},
1613 { "tokenGroupsGlobalAndUniversal", LDB_SYNTAX_SAMBA_SID
},
1614 { "tokenGroupsNoGCAcceptable", LDB_SYNTAX_SAMBA_SID
},
1615 { "securityIdentifier", LDB_SYNTAX_SAMBA_SID
},
1616 { "sIDHistory", LDB_SYNTAX_SAMBA_SID
},
1617 { "syncWithSID", LDB_SYNTAX_SAMBA_SID
},
1620 * these are extracted by searching
1621 * (&(attributeSyntax=2.5.5.10)(rangeLower=16)(rangeUpper=16)(omSyntax=4))
1623 { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID
},
1624 { "categoryId", LDB_SYNTAX_SAMBA_GUID
},
1625 { "controlAccessRights", LDB_SYNTAX_SAMBA_GUID
},
1626 { "currMachineId", LDB_SYNTAX_SAMBA_GUID
},
1627 { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID
},
1628 { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID
},
1629 { "implementedCategories", LDB_SYNTAX_SAMBA_GUID
},
1630 { "msDS-AzObjectGuid", LDB_SYNTAX_SAMBA_GUID
},
1631 { "msDS-GenerationId", LDB_SYNTAX_SAMBA_GUID
},
1632 { "msDS-OptionalFeatureGUID", LDB_SYNTAX_SAMBA_GUID
},
1633 { "msDFSR-ContentSetGuid", LDB_SYNTAX_SAMBA_GUID
},
1634 { "msDFSR-ReplicationGroupGuid", LDB_SYNTAX_SAMBA_GUID
},
1635 { "mSMQDigests", LDB_SYNTAX_SAMBA_GUID
},
1636 { "mSMQOwnerID", LDB_SYNTAX_SAMBA_GUID
},
1637 { "mSMQQMID", LDB_SYNTAX_SAMBA_GUID
},
1638 { "mSMQQueueType", LDB_SYNTAX_SAMBA_GUID
},
1639 { "mSMQSites", LDB_SYNTAX_SAMBA_GUID
},
1640 { "netbootGUID", LDB_SYNTAX_SAMBA_GUID
},
1641 { "objectGUID", LDB_SYNTAX_SAMBA_GUID
},
1642 { "pKTGuid", LDB_SYNTAX_SAMBA_GUID
},
1643 { "requiredCategories", LDB_SYNTAX_SAMBA_GUID
},
1644 { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID
},
1645 { "siteGUID", LDB_SYNTAX_SAMBA_GUID
},
1646 { "msDFS-GenerationGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1647 { "msDFS-LinkIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1648 { "msDFS-NamespaceIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1649 { "msSPP-CSVLKSkuId", LDB_SYNTAX_SAMBA_GUID
},
1650 { "msSPP-KMSIds", LDB_SYNTAX_SAMBA_GUID
},
1653 * these are known to be GUIDs
1655 { "invocationId", LDB_SYNTAX_SAMBA_GUID
},
1656 { "parentGUID", LDB_SYNTAX_SAMBA_GUID
},
1658 /* These NDR encoded things we want to be able to read with --show-binary */
1659 { "dnsRecord", LDB_SYNTAX_SAMBA_DNSRECORD
},
1660 { "dNSProperty", LDB_SYNTAX_SAMBA_DNSPROPERTY
},
1661 { "supplementalCredentials", LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS
},
1662 { "partialAttributeSet", LDB_SYNTAX_SAMBA_PARTIALATTRIBUTESET
}
1665 const struct ldb_schema_syntax
*ldb_samba_syntax_by_name(struct ldb_context
*ldb
, const char *name
)
1668 const struct ldb_schema_syntax
*s
= NULL
;
1670 for (j
=0; j
< ARRAY_SIZE(samba_syntaxes
); j
++) {
1671 if (strcmp(name
, samba_syntaxes
[j
].name
) == 0) {
1672 s
= &samba_syntaxes
[j
];
1679 const struct ldb_schema_syntax
*ldb_samba_syntax_by_lDAPDisplayName(struct ldb_context
*ldb
, const char *name
)
1682 const struct ldb_schema_syntax
*s
= NULL
;
1684 for (j
=0; j
< ARRAY_SIZE(samba_attributes
); j
++) {
1685 if (strcmp(samba_attributes
[j
].name
, name
) == 0) {
1686 s
= ldb_samba_syntax_by_name(ldb
, samba_attributes
[j
].syntax
);
1694 static const char *secret_attributes
[] = {DSDB_SECRET_ATTRIBUTES
, "secret", NULL
};
1697 register the samba ldif handlers
1699 int ldb_register_samba_handlers(struct ldb_context
*ldb
)
1704 if (ldb_get_opaque(ldb
, "SAMBA_HANDLERS_REGISTERED") != NULL
) {
1708 ret
= ldb_set_opaque(ldb
, LDB_SECRET_ATTRIBUTE_LIST_OPAQUE
, discard_const_p(char *, secret_attributes
));
1709 if (ret
!= LDB_SUCCESS
) {
1713 for (i
=0; i
< ARRAY_SIZE(samba_attributes
); i
++) {
1714 const struct ldb_schema_syntax
*s
= NULL
;
1716 s
= ldb_samba_syntax_by_name(ldb
, samba_attributes
[i
].syntax
);
1719 s
= ldb_standard_syntax_by_name(ldb
, samba_attributes
[i
].syntax
);
1723 return LDB_ERR_OPERATIONS_ERROR
;
1726 ret
= ldb_schema_attribute_add_with_syntax(ldb
, samba_attributes
[i
].name
, LDB_ATTR_FLAG_FIXED
, s
);
1727 if (ret
!= LDB_SUCCESS
) {
1732 for (i
=0; i
< ARRAY_SIZE(samba_dn_syntax
); i
++) {
1733 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &samba_dn_syntax
[i
]);
1734 if (ret
!= LDB_SUCCESS
) {
1740 ret
= ldb_register_samba_matching_rules(ldb
);
1741 if (ret
!= LDB_SUCCESS
) {
1746 ret
= ldb_set_opaque(ldb
, "SAMBA_HANDLERS_REGISTERED", (void*)1);
1747 if (ret
!= LDB_SUCCESS
) {