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 "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/gen_ndr/ndr_dnsp.h"
34 #include "librpc/ndr/libndr.h"
35 #include "libcli/security/security.h"
36 #include "param/param.h"
37 #include "../lib/util/asn1.h"
40 use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob
42 If mask_errors is true, then function succeeds but out data
43 is set to "<Unable to decode binary data>" message
45 \return 0 on success; -1 on error
47 static int ldif_write_NDR(struct ldb_context
*ldb
, void *mem_ctx
,
48 const struct ldb_val
*in
, struct ldb_val
*out
,
50 ndr_pull_flags_fn_t pull_fn
,
51 ndr_print_fn_t print_fn
,
55 enum ndr_err_code err
;
56 if (!(ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
)) {
57 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
59 p
= talloc_size(mem_ctx
, struct_size
);
60 err
= ndr_pull_struct_blob(in
, mem_ctx
,
62 if (err
!= NDR_ERR_SUCCESS
) {
63 /* fail in not in mask_error mode */
68 out
->data
= (uint8_t *)talloc_strdup(mem_ctx
, "<Unable to decode binary data>");
69 out
->length
= strlen((const char *)out
->data
);
72 out
->data
= (uint8_t *)ndr_print_struct_string(mem_ctx
, print_fn
, "NDR", p
);
74 if (out
->data
== NULL
) {
75 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
77 out
->length
= strlen((char *)out
->data
);
82 convert a ldif formatted objectSid to a NDR formatted blob
84 static int ldif_read_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
85 const struct ldb_val
*in
, struct ldb_val
*out
)
87 enum ndr_err_code ndr_err
;
89 sid
= dom_sid_parse_length(mem_ctx
, in
);
93 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
, sid
,
94 (ndr_push_flags_fn_t
)ndr_push_dom_sid
);
96 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
103 convert a NDR formatted blob to a ldif formatted objectSid
105 int ldif_write_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
106 const struct ldb_val
*in
, struct ldb_val
*out
)
109 enum ndr_err_code ndr_err
;
111 sid
= talloc(mem_ctx
, struct dom_sid
);
115 ndr_err
= ndr_pull_struct_blob_all(in
, sid
, sid
,
116 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
117 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
121 *out
= data_blob_string_const(dom_sid_string(mem_ctx
, sid
));
123 if (out
->data
== NULL
) {
129 bool ldif_comparision_objectSid_isString(const struct ldb_val
*v
)
135 if (strncmp("S-", (const char *)v
->data
, 2) != 0) return false;
141 compare two objectSids
143 static int ldif_comparison_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
144 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
146 if (ldif_comparision_objectSid_isString(v1
) && ldif_comparision_objectSid_isString(v2
)) {
147 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
148 } else if (ldif_comparision_objectSid_isString(v1
)
149 && !ldif_comparision_objectSid_isString(v2
)) {
152 if (ldif_read_objectSid(ldb
, mem_ctx
, v1
, &v
) != 0) {
153 /* Perhaps not a string after all */
154 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
156 ret
= ldb_comparison_binary(ldb
, mem_ctx
, &v
, v2
);
159 } else if (!ldif_comparision_objectSid_isString(v1
)
160 && ldif_comparision_objectSid_isString(v2
)) {
163 if (ldif_read_objectSid(ldb
, mem_ctx
, v2
, &v
) != 0) {
164 /* Perhaps not a string after all */
165 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
167 ret
= ldb_comparison_binary(ldb
, mem_ctx
, v1
, &v
);
171 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
175 canonicalise a objectSid
177 static int ldif_canonicalise_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
178 const struct ldb_val
*in
, struct ldb_val
*out
)
180 if (ldif_comparision_objectSid_isString(in
)) {
181 if (ldif_read_objectSid(ldb
, mem_ctx
, in
, out
) != 0) {
182 /* Perhaps not a string after all */
183 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
187 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
190 static int extended_dn_read_SID(struct ldb_context
*ldb
, void *mem_ctx
,
191 const struct ldb_val
*in
, struct ldb_val
*out
)
194 enum ndr_err_code ndr_err
;
195 if (ldif_comparision_objectSid_isString(in
)) {
196 if (ldif_read_objectSid(ldb
, mem_ctx
, in
, out
) == 0) {
201 /* Perhaps not a string after all */
202 *out
= data_blob_talloc(mem_ctx
, NULL
, in
->length
/2+1);
208 (*out
).length
= strhex_to_str((char *)out
->data
, out
->length
,
209 (const char *)in
->data
, in
->length
);
211 /* Check it looks like a SID */
212 ndr_err
= ndr_pull_struct_blob_all(out
, mem_ctx
, &sid
,
213 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
214 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
221 convert a ldif formatted objectGUID to a NDR formatted blob
223 static int ldif_read_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
224 const struct ldb_val
*in
, struct ldb_val
*out
)
229 status
= GUID_from_data_blob(in
, &guid
);
230 if (!NT_STATUS_IS_OK(status
)) {
234 status
= GUID_to_ndr_blob(&guid
, mem_ctx
, out
);
235 if (!NT_STATUS_IS_OK(status
)) {
242 convert a NDR formatted blob to a ldif formatted objectGUID
244 static int ldif_write_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
245 const struct ldb_val
*in
, struct ldb_val
*out
)
250 status
= GUID_from_ndr_blob(in
, &guid
);
251 if (!NT_STATUS_IS_OK(status
)) {
254 out
->data
= (uint8_t *)GUID_string(mem_ctx
, &guid
);
255 if (out
->data
== NULL
) {
258 out
->length
= strlen((const char *)out
->data
);
262 static bool ldif_comparision_objectGUID_isString(const struct ldb_val
*v
)
264 if (v
->length
!= 36 && v
->length
!= 38) return false;
266 /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */
270 static int extended_dn_read_GUID(struct ldb_context
*ldb
, void *mem_ctx
,
271 const struct ldb_val
*in
, struct ldb_val
*out
)
276 if (in
->length
== 36 && ldif_read_objectGUID(ldb
, mem_ctx
, in
, out
) == 0) {
280 /* Try as 'hex' form */
281 if (in
->length
!= 32) {
285 *out
= data_blob_talloc(mem_ctx
, NULL
, in
->length
/2+1);
291 (*out
).length
= strhex_to_str((char *)out
->data
, out
->length
,
292 (const char *)in
->data
, in
->length
);
294 /* Check it looks like a GUID */
295 status
= GUID_from_ndr_blob(out
, &guid
);
296 if (!NT_STATUS_IS_OK(status
)) {
304 compare two objectGUIDs
306 static int ldif_comparison_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
307 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
309 if (ldif_comparision_objectGUID_isString(v1
) && ldif_comparision_objectGUID_isString(v2
)) {
310 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
311 } else if (ldif_comparision_objectGUID_isString(v1
)
312 && !ldif_comparision_objectGUID_isString(v2
)) {
315 if (ldif_read_objectGUID(ldb
, mem_ctx
, v1
, &v
) != 0) {
316 /* Perhaps it wasn't a valid string after all */
317 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
319 ret
= ldb_comparison_binary(ldb
, mem_ctx
, &v
, v2
);
322 } else if (!ldif_comparision_objectGUID_isString(v1
)
323 && ldif_comparision_objectGUID_isString(v2
)) {
326 if (ldif_read_objectGUID(ldb
, mem_ctx
, v2
, &v
) != 0) {
327 /* Perhaps it wasn't a valid string after all */
328 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
330 ret
= ldb_comparison_binary(ldb
, mem_ctx
, v1
, &v
);
334 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
338 canonicalise a objectGUID
340 static int ldif_canonicalise_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
341 const struct ldb_val
*in
, struct ldb_val
*out
)
343 if (ldif_comparision_objectGUID_isString(in
)) {
344 if (ldif_read_objectGUID(ldb
, mem_ctx
, in
, out
) != 0) {
345 /* Perhaps it wasn't a valid string after all */
346 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
350 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
355 convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob
357 static int ldif_read_ntSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
358 const struct ldb_val
*in
, struct ldb_val
*out
)
360 struct security_descriptor
*sd
;
361 enum ndr_err_code ndr_err
;
363 sd
= talloc(mem_ctx
, struct security_descriptor
);
368 ndr_err
= ndr_pull_struct_blob(in
, sd
, sd
,
369 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
370 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
371 /* If this does not parse, then it is probably SDDL, and we should try it that way */
373 const struct dom_sid
*sid
= samdb_domain_sid(ldb
);
375 sd
= sddl_decode(mem_ctx
, (const char *)in
->data
, sid
);
381 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
, sd
,
382 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
);
384 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
392 convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format)
394 static int ldif_write_ntSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
395 const struct ldb_val
*in
, struct ldb_val
*out
)
397 struct security_descriptor
*sd
;
398 enum ndr_err_code ndr_err
;
400 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
401 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
402 sizeof(struct security_descriptor
),
403 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
,
404 (ndr_print_fn_t
)ndr_print_security_descriptor
,
409 sd
= talloc(mem_ctx
, struct security_descriptor
);
413 /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
414 ndr_err
= ndr_pull_struct_blob(in
, sd
, sd
,
415 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
416 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
420 out
->data
= (uint8_t *)sddl_encode(mem_ctx
, sd
, samdb_domain_sid_cache_only(ldb
));
422 if (out
->data
== NULL
) {
425 out
->length
= strlen((const char *)out
->data
);
430 convert a string formatted SDDL to a ldif formatted ntSecurityDescriptor (SDDL format)
432 static int ldif_write_sddlSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
433 const struct ldb_val
*in
, struct ldb_val
*out
)
435 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
436 struct security_descriptor
*sd
;
437 const struct dom_sid
*sid
= samdb_domain_sid(ldb
);
439 sd
= sddl_decode(mem_ctx
, (const char *)in
->data
, sid
);
440 out
->data
= (uint8_t *)ndr_print_struct_string(mem_ctx
,
441 (ndr_print_fn_t
)ndr_print_security_descriptor
,
443 out
->length
= strlen((const char *)out
->data
);
448 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
452 canonicalise an objectCategory. We use the long form as the canonical form:
453 'person' becomes cn=Person,cn=Schema,cn=Configuration,<basedn>
455 Also any short name of an objectClass that points to a different
456 class (such as user) has the canonical form of the class it's
457 defaultObjectCategory points to (eg
458 cn=Person,cn=Schema,cn=Configuration,<basedn>)
461 static int ldif_canonicalise_objectCategory(struct ldb_context
*ldb
, void *mem_ctx
,
462 const struct ldb_val
*in
, struct ldb_val
*out
)
464 struct ldb_dn
*dn1
= NULL
;
465 const struct dsdb_schema
*schema
= dsdb_get_schema(ldb
, NULL
);
466 const struct dsdb_class
*sclass
;
467 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
469 return LDB_ERR_OPERATIONS_ERROR
;
473 talloc_free(tmp_ctx
);
474 *out
= data_blob_talloc(mem_ctx
, in
->data
, in
->length
);
475 if (in
->data
&& !out
->data
) {
476 return LDB_ERR_OPERATIONS_ERROR
;
480 dn1
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, in
);
481 if ( ! ldb_dn_validate(dn1
)) {
482 const char *lDAPDisplayName
= talloc_strndup(tmp_ctx
, (char *)in
->data
, in
->length
);
483 sclass
= dsdb_class_by_lDAPDisplayName(schema
, lDAPDisplayName
);
485 struct ldb_dn
*dn
= ldb_dn_new(mem_ctx
, ldb
,
486 sclass
->defaultObjectCategory
);
487 *out
= data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx
, dn
));
488 talloc_free(tmp_ctx
);
491 return LDB_ERR_OPERATIONS_ERROR
;
495 *out
= data_blob_talloc(mem_ctx
, in
->data
, in
->length
);
496 talloc_free(tmp_ctx
);
498 if (in
->data
&& !out
->data
) {
499 return LDB_ERR_OPERATIONS_ERROR
;
504 *out
= data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx
, dn1
));
505 talloc_free(tmp_ctx
);
508 return LDB_ERR_OPERATIONS_ERROR
;
513 static int ldif_comparison_objectCategory(struct ldb_context
*ldb
, void *mem_ctx
,
514 const struct ldb_val
*v1
,
515 const struct ldb_val
*v2
)
517 return ldb_any_comparison(ldb
, mem_ctx
, ldif_canonicalise_objectCategory
,
522 convert a NDR formatted blob to a ldif formatted schemaInfo
524 static int ldif_write_schemaInfo(struct ldb_context
*ldb
, void *mem_ctx
,
525 const struct ldb_val
*in
, struct ldb_val
*out
)
527 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
528 sizeof(struct repsFromToBlob
),
529 (ndr_pull_flags_fn_t
)ndr_pull_schemaInfoBlob
,
530 (ndr_print_fn_t
)ndr_print_schemaInfoBlob
,
535 convert a ldif formatted prefixMap to a NDR formatted blob
537 static int ldif_read_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
538 const struct ldb_val
*in
, struct ldb_val
*out
)
540 struct prefixMapBlob
*blob
;
541 enum ndr_err_code ndr_err
;
542 char *string
, *line
, *p
, *oid
;
545 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
547 if (tmp_ctx
== NULL
) {
551 blob
= talloc_zero(tmp_ctx
, struct prefixMapBlob
);
553 talloc_free(tmp_ctx
);
557 /* use the switch value to detect if this is in the binary
560 if (in
->length
>= 4 && IVAL(in
->data
, 0) == PREFIX_MAP_VERSION_DSDB
) {
561 ndr_err
= ndr_pull_struct_blob(in
, tmp_ctx
, blob
,
562 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
);
563 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
564 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
,
566 (ndr_push_flags_fn_t
)ndr_push_prefixMapBlob
);
567 talloc_free(tmp_ctx
);
568 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
575 /* If this does not parse, then it is probably the text version, and we should try it that way */
576 blob
->version
= PREFIX_MAP_VERSION_DSDB
;
578 string
= talloc_strndup(mem_ctx
, (const char *)in
->data
, in
->length
);
579 if (string
== NULL
) {
585 while (line
&& line
[0]) {
590 p
=strchr(line
, '\n');
595 /* allow a trailing separator */
600 blob
->ctr
.dsdb
.mappings
= talloc_realloc(blob
,
601 blob
->ctr
.dsdb
.mappings
,
602 struct drsuapi_DsReplicaOIDMapping
,
603 blob
->ctr
.dsdb
.num_mappings
+1);
604 if (!blob
->ctr
.dsdb
.mappings
) {
605 talloc_free(tmp_ctx
);
609 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].id_prefix
= strtoul(line
, &oid
, 10);
612 talloc_free(tmp_ctx
);
616 /* we know there must be at least ":" */
619 if (!ber_write_partial_OID_String(blob
->ctr
.dsdb
.mappings
, &oid_blob
, oid
)) {
620 talloc_free(tmp_ctx
);
623 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].oid
.length
= oid_blob
.length
;
624 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].oid
.binary_oid
= oid_blob
.data
;
626 blob
->ctr
.dsdb
.num_mappings
++;
628 /* Now look past the terminator we added above */
636 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
,
638 (ndr_push_flags_fn_t
)ndr_push_prefixMapBlob
);
639 talloc_free(tmp_ctx
);
640 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
647 convert a NDR formatted blob to a ldif formatted prefixMap
649 static int ldif_write_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
650 const struct ldb_val
*in
, struct ldb_val
*out
)
652 struct prefixMapBlob
*blob
;
653 enum ndr_err_code ndr_err
;
657 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
659 /* try to decode the blob as S4 prefixMap */
660 err
= ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
661 sizeof(struct prefixMapBlob
),
662 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
,
663 (ndr_print_fn_t
)ndr_print_prefixMapBlob
,
668 /* try parsing it as Windows PrefixMap value */
669 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
670 sizeof(struct drsuapi_MSPrefixMap_Ctr
),
671 (ndr_pull_flags_fn_t
)ndr_pull_drsuapi_MSPrefixMap_Ctr
,
672 (ndr_print_fn_t
)ndr_print_drsuapi_MSPrefixMap_Ctr
,
676 blob
= talloc(mem_ctx
, struct prefixMapBlob
);
680 ndr_err
= ndr_pull_struct_blob_all(in
, blob
,
682 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
);
683 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
686 if (blob
->version
!= PREFIX_MAP_VERSION_DSDB
) {
689 string
= talloc_strdup(mem_ctx
, "");
690 if (string
== NULL
) {
694 for (i
=0; i
< blob
->ctr
.dsdb
.num_mappings
; i
++) {
696 char *partial_oid
= NULL
;
699 string
= talloc_asprintf_append(string
, ";");
702 oid_blob
= data_blob_const(blob
->ctr
.dsdb
.mappings
[i
].oid
.binary_oid
,
703 blob
->ctr
.dsdb
.mappings
[i
].oid
.length
);
704 if (!ber_read_partial_OID_String(blob
, oid_blob
, &partial_oid
)) {
705 DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X",
706 blob
->ctr
.dsdb
.mappings
[i
].id_prefix
));
709 string
= talloc_asprintf_append(string
, "%u:%s",
710 blob
->ctr
.dsdb
.mappings
[i
].id_prefix
,
712 talloc_free(discard_const(partial_oid
));
713 if (string
== NULL
) {
719 *out
= data_blob_string_const(string
);
727 static bool ldif_comparision_prefixMap_isString(const struct ldb_val
*v
)
733 if (IVAL(v
->data
, 0) == PREFIX_MAP_VERSION_DSDB
) {
741 canonicalise a prefixMap
743 static int ldif_canonicalise_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
744 const struct ldb_val
*in
, struct ldb_val
*out
)
746 if (ldif_comparision_prefixMap_isString(in
)) {
747 return ldif_read_prefixMap(ldb
, mem_ctx
, in
, out
);
749 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
752 static int ldif_comparison_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
753 const struct ldb_val
*v1
,
754 const struct ldb_val
*v2
)
756 return ldb_any_comparison(ldb
, mem_ctx
, ldif_canonicalise_prefixMap
,
760 /* length limited conversion of a ldb_val to a int32_t */
761 static int val_to_int32(const struct ldb_val
*in
, int32_t *v
)
766 /* make sure we don't read past the end of the data */
767 if (in
->length
> sizeof(buf
)-1) {
768 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
770 strncpy(buf
, (char *)in
->data
, in
->length
);
773 /* We've to use "strtoll" here to have the intended overflows.
774 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
775 *v
= (int32_t) strtoll(buf
, &end
, 0);
777 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
782 /* length limited conversion of a ldb_val to a int64_t */
783 static int val_to_int64(const struct ldb_val
*in
, int64_t *v
)
788 /* make sure we don't read past the end of the data */
789 if (in
->length
> sizeof(buf
)-1) {
790 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
792 strncpy(buf
, (char *)in
->data
, in
->length
);
795 *v
= (int64_t) strtoll(buf
, &end
, 0);
797 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
802 /* Canonicalisation of two 32-bit integers */
803 static int ldif_canonicalise_int32(struct ldb_context
*ldb
, void *mem_ctx
,
804 const struct ldb_val
*in
, struct ldb_val
*out
)
809 ret
= val_to_int32(in
, &i
);
810 if (ret
!= LDB_SUCCESS
) {
813 out
->data
= (uint8_t *) talloc_asprintf(mem_ctx
, "%d", i
);
814 if (out
->data
== NULL
) {
816 return LDB_ERR_OPERATIONS_ERROR
;
818 out
->length
= strlen((char *)out
->data
);
822 /* Comparison of two 32-bit integers */
823 static int ldif_comparison_int32(struct ldb_context
*ldb
, void *mem_ctx
,
824 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
827 val_to_int32(v1
, &i1
);
828 val_to_int32(v2
, &i2
);
829 if (i1
== i2
) return 0;
830 return i1
> i2
? 1 : -1;
833 /* Canonicalisation of two 64-bit integers */
834 static int ldif_canonicalise_int64(struct ldb_context
*ldb
, void *mem_ctx
,
835 const struct ldb_val
*in
, struct ldb_val
*out
)
840 ret
= val_to_int64(in
, &i
);
841 if (ret
!= LDB_SUCCESS
) {
844 out
->data
= (uint8_t *) talloc_asprintf(mem_ctx
, "%lld", (long long)i
);
845 if (out
->data
== NULL
) {
847 return LDB_ERR_OPERATIONS_ERROR
;
849 out
->length
= strlen((char *)out
->data
);
853 /* Comparison of two 64-bit integers */
854 static int ldif_comparison_int64(struct ldb_context
*ldb
, void *mem_ctx
,
855 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
858 val_to_int64(v1
, &i1
);
859 val_to_int64(v2
, &i2
);
860 if (i1
== i2
) return 0;
861 return i1
> i2
? 1 : -1;
865 convert a NDR formatted blob to a ldif formatted repsFromTo
867 static int ldif_write_repsFromTo(struct ldb_context
*ldb
, void *mem_ctx
,
868 const struct ldb_val
*in
, struct ldb_val
*out
)
870 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
871 sizeof(struct repsFromToBlob
),
872 (ndr_pull_flags_fn_t
)ndr_pull_repsFromToBlob
,
873 (ndr_print_fn_t
)ndr_print_repsFromToBlob
,
878 convert a NDR formatted blob to a ldif formatted replPropertyMetaData
880 static int ldif_write_replPropertyMetaData(struct ldb_context
*ldb
, void *mem_ctx
,
881 const struct ldb_val
*in
, struct ldb_val
*out
)
883 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
884 sizeof(struct replPropertyMetaDataBlob
),
885 (ndr_pull_flags_fn_t
)ndr_pull_replPropertyMetaDataBlob
,
886 (ndr_print_fn_t
)ndr_print_replPropertyMetaDataBlob
,
891 convert a NDR formatted blob to a ldif formatted replUpToDateVector
893 static int ldif_write_replUpToDateVector(struct ldb_context
*ldb
, void *mem_ctx
,
894 const struct ldb_val
*in
, struct ldb_val
*out
)
896 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
897 sizeof(struct replUpToDateVectorBlob
),
898 (ndr_pull_flags_fn_t
)ndr_pull_replUpToDateVectorBlob
,
899 (ndr_print_fn_t
)ndr_print_replUpToDateVectorBlob
,
905 convert a NDR formatted blob to a ldif formatted dnsRecord
907 static int ldif_write_dnsRecord(struct ldb_context
*ldb
, void *mem_ctx
,
908 const struct ldb_val
*in
, struct ldb_val
*out
)
910 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
911 sizeof(struct dnsp_DnssrvRpcRecord
),
912 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
,
913 (ndr_print_fn_t
)ndr_print_dnsp_DnssrvRpcRecord
,
918 convert a NDR formatted blob to a ldif formatted dnsProperty
920 static int ldif_write_dnsProperty(struct ldb_context
*ldb
, void *mem_ctx
,
921 const struct ldb_val
*in
, struct ldb_val
*out
)
923 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
924 sizeof(struct dnsp_DnsProperty
),
925 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnsProperty
,
926 (ndr_print_fn_t
)ndr_print_dnsp_DnsProperty
,
931 convert a NDR formatted blob of a supplementalCredentials into text
933 static int ldif_write_supplementalCredentialsBlob(struct ldb_context
*ldb
, void *mem_ctx
,
934 const struct ldb_val
*in
, struct ldb_val
*out
)
936 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
937 sizeof(struct supplementalCredentialsBlob
),
938 (ndr_pull_flags_fn_t
)ndr_pull_supplementalCredentialsBlob
,
939 (ndr_print_fn_t
)ndr_print_supplementalCredentialsBlob
,
944 convert a NDR formatted blob to a ldif formatted trustAuthInOutBlob
946 static int ldif_write_trustAuthInOutBlob(struct ldb_context
*ldb
, void *mem_ctx
,
947 const struct ldb_val
*in
, struct ldb_val
*out
)
949 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
950 sizeof(struct trustAuthInOutBlob
),
951 (ndr_pull_flags_fn_t
)ndr_pull_trustAuthInOutBlob
,
952 (ndr_print_fn_t
)ndr_print_trustAuthInOutBlob
,
957 convert a NDR formatted blob of a partialAttributeSet into text
959 static int ldif_write_partialAttributeSet(struct ldb_context
*ldb
, void *mem_ctx
,
960 const struct ldb_val
*in
, struct ldb_val
*out
)
962 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
963 sizeof(struct partialAttributeSetBlob
),
964 (ndr_pull_flags_fn_t
)ndr_pull_partialAttributeSetBlob
,
965 (ndr_print_fn_t
)ndr_print_partialAttributeSetBlob
,
970 static int extended_dn_write_hex(struct ldb_context
*ldb
, void *mem_ctx
,
971 const struct ldb_val
*in
, struct ldb_val
*out
)
973 *out
= data_blob_string_const(data_blob_hex_string_lower(mem_ctx
, in
));
983 static int samba_ldb_dn_link_comparison(struct ldb_context
*ldb
, void *mem_ctx
,
984 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
986 struct ldb_dn
*dn1
= NULL
, *dn2
= NULL
;
989 if (dsdb_dn_is_deleted_val(v1
)) {
990 /* If the DN is deleted, then we can't search for it */
994 if (dsdb_dn_is_deleted_val(v2
)) {
995 /* If the DN is deleted, then we can't search for it */
999 dn1
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, v1
);
1000 if ( ! ldb_dn_validate(dn1
)) return -1;
1002 dn2
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, v2
);
1003 if ( ! ldb_dn_validate(dn2
)) {
1008 ret
= ldb_dn_compare(dn1
, dn2
);
1015 static int samba_ldb_dn_link_canonicalise(struct ldb_context
*ldb
, void *mem_ctx
,
1016 const struct ldb_val
*in
, struct ldb_val
*out
)
1024 dn
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, in
);
1025 if ( ! ldb_dn_validate(dn
)) {
1026 return LDB_ERR_INVALID_DN_SYNTAX
;
1029 /* By including the RMD_FLAGS of a deleted DN, we ensure it
1030 * does not casually match a not deleted DN */
1031 if (dsdb_dn_is_deleted_val(in
)) {
1032 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
,
1034 dsdb_dn_val_rmd_flags(in
),
1035 ldb_dn_get_casefold(dn
));
1037 out
->data
= (uint8_t *)ldb_dn_alloc_casefold(mem_ctx
, dn
);
1040 if (out
->data
== NULL
) {
1043 out
->length
= strlen((char *)out
->data
);
1055 write a 64 bit 2-part range
1057 static int ldif_write_range64(struct ldb_context
*ldb
, void *mem_ctx
,
1058 const struct ldb_val
*in
, struct ldb_val
*out
)
1062 ret
= val_to_int64(in
, &v
);
1063 if (ret
!= LDB_SUCCESS
) {
1066 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
, "%lu-%lu",
1067 (unsigned long)(v
&0xFFFFFFFF),
1068 (unsigned long)(v
>>32));
1069 if (out
->data
== NULL
) {
1071 return LDB_ERR_OPERATIONS_ERROR
;
1073 out
->length
= strlen((char *)out
->data
);
1078 read a 64 bit 2-part range
1080 static int ldif_read_range64(struct ldb_context
*ldb
, void *mem_ctx
,
1081 const struct ldb_val
*in
, struct ldb_val
*out
)
1083 unsigned long high
, low
;
1086 if (memchr(in
->data
, '-', in
->length
) == NULL
) {
1087 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1090 if (in
->length
> sizeof(buf
)-1) {
1091 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
1093 strncpy(buf
, (const char *)in
->data
, in
->length
);
1094 buf
[in
->length
] = 0;
1096 if (sscanf(buf
, "%lu-%lu", &low
, &high
) != 2) {
1097 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
1100 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
, "%llu",
1101 (unsigned long long)(((uint64_t)high
)<<32) | (low
));
1103 if (out
->data
== NULL
) {
1105 return LDB_ERR_OPERATIONS_ERROR
;
1107 out
->length
= strlen((char *)out
->data
);
1112 when this operator_fn is set for a syntax, the backend calls is in
1113 preference to the comparison function. We are told the exact
1114 comparison operation that is needed, and we can return errors
1116 static int samba_syntax_operator_fn(struct ldb_context
*ldb
, enum ldb_parse_op operation
,
1117 const struct ldb_schema_attribute
*a
,
1118 const struct ldb_val
*v1
, const struct ldb_val
*v2
, bool *matched
)
1120 switch (operation
) {
1124 case LDB_OP_SUBSTRING
:
1126 case LDB_OP_EXTENDED
:
1127 /* handled in the backends */
1128 return LDB_ERR_INAPPROPRIATE_MATCHING
;
1130 case LDB_OP_GREATER
:
1132 case LDB_OP_EQUALITY
:
1134 TALLOC_CTX
*tmp_ctx
= talloc_new(ldb
);
1136 if (tmp_ctx
== NULL
) {
1137 return ldb_oom(ldb
);
1139 ret
= a
->syntax
->comparison_fn(ldb
, tmp_ctx
, v1
, v2
);
1140 talloc_free(tmp_ctx
);
1141 if (operation
== LDB_OP_GREATER
) {
1142 *matched
= (ret
>= 0);
1143 } else if (operation
== LDB_OP_LESS
) {
1144 *matched
= (ret
<= 0);
1146 *matched
= (ret
== 0);
1151 case LDB_OP_PRESENT
:
1156 /* we shouldn't get here */
1157 return LDB_ERR_INAPPROPRIATE_MATCHING
;
1161 see if two DNs match, comparing first by GUID, then by SID, and
1162 finally by string components
1164 static int samba_dn_extended_match(struct ldb_context
*ldb
,
1165 const struct ldb_val
*v1
,
1166 const struct ldb_val
*v2
,
1169 TALLOC_CTX
*tmp_ctx
;
1170 struct ldb_dn
*dn1
, *dn2
;
1171 const struct ldb_val
*guid1
, *guid2
, *sid1
, *sid2
;
1172 uint32_t rmd_flags1
, rmd_flags2
;
1174 tmp_ctx
= talloc_new(ldb
);
1176 dn1
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, v1
);
1177 dn2
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, v2
);
1179 /* couldn't parse as DN's */
1180 talloc_free(tmp_ctx
);
1185 rmd_flags1
= dsdb_dn_rmd_flags(dn1
);
1186 rmd_flags2
= dsdb_dn_rmd_flags(dn2
);
1188 if ((rmd_flags1
& DSDB_RMD_FLAG_DELETED
) !=
1189 (rmd_flags2
& DSDB_RMD_FLAG_DELETED
)) {
1190 /* only match if they have the same deletion status */
1191 talloc_free(tmp_ctx
);
1197 guid1
= ldb_dn_get_extended_component(dn1
, "GUID");
1198 guid2
= ldb_dn_get_extended_component(dn2
, "GUID");
1199 if (guid1
&& guid2
) {
1200 (*matched
) = (data_blob_cmp(guid1
, guid2
) == 0);
1201 talloc_free(tmp_ctx
);
1205 sid1
= ldb_dn_get_extended_component(dn1
, "SID");
1206 sid2
= ldb_dn_get_extended_component(dn2
, "SID");
1208 (*matched
) = (data_blob_cmp(sid1
, sid2
) == 0);
1209 talloc_free(tmp_ctx
);
1213 (*matched
) = (ldb_dn_compare(dn1
, dn2
) == 0);
1215 talloc_free(tmp_ctx
);
1220 special operation for DNs, to take account of the RMD_FLAGS deleted bit
1222 static int samba_syntax_operator_dn(struct ldb_context
*ldb
, enum ldb_parse_op operation
,
1223 const struct ldb_schema_attribute
*a
,
1224 const struct ldb_val
*v1
, const struct ldb_val
*v2
, bool *matched
)
1226 if (operation
== LDB_OP_PRESENT
&& dsdb_dn_is_deleted_val(v1
)) {
1227 /* If the DN is deleted, then we can't search for it */
1229 /* should this be for equality too? */
1234 if (operation
== LDB_OP_EQUALITY
&&
1235 samba_dn_extended_match(ldb
, v1
, v2
, matched
) == LDB_SUCCESS
) {
1239 return samba_syntax_operator_fn(ldb
, operation
, a
, v1
, v2
, matched
);
1243 static const struct ldb_schema_syntax samba_syntaxes
[] = {
1245 .name
= LDB_SYNTAX_SAMBA_SID
,
1246 .ldif_read_fn
= ldif_read_objectSid
,
1247 .ldif_write_fn
= ldif_write_objectSid
,
1248 .canonicalise_fn
= ldif_canonicalise_objectSid
,
1249 .comparison_fn
= ldif_comparison_objectSid
,
1250 .operator_fn
= samba_syntax_operator_fn
1252 .name
= LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR
,
1253 .ldif_read_fn
= ldif_read_ntSecurityDescriptor
,
1254 .ldif_write_fn
= ldif_write_ntSecurityDescriptor
,
1255 .canonicalise_fn
= ldb_handler_copy
,
1256 .comparison_fn
= ldb_comparison_binary
,
1257 .operator_fn
= samba_syntax_operator_fn
1259 .name
= LDB_SYNTAX_SAMBA_SDDL_SECURITY_DESCRIPTOR
,
1260 .ldif_read_fn
= ldb_handler_copy
,
1261 .ldif_write_fn
= ldif_write_sddlSecurityDescriptor
,
1262 .canonicalise_fn
= ldb_handler_fold
,
1263 .comparison_fn
= ldb_comparison_fold
,
1264 .operator_fn
= samba_syntax_operator_fn
1266 .name
= LDB_SYNTAX_SAMBA_GUID
,
1267 .ldif_read_fn
= ldif_read_objectGUID
,
1268 .ldif_write_fn
= ldif_write_objectGUID
,
1269 .canonicalise_fn
= ldif_canonicalise_objectGUID
,
1270 .comparison_fn
= ldif_comparison_objectGUID
,
1271 .operator_fn
= samba_syntax_operator_fn
1273 .name
= LDB_SYNTAX_SAMBA_OBJECT_CATEGORY
,
1274 .ldif_read_fn
= ldb_handler_copy
,
1275 .ldif_write_fn
= ldb_handler_copy
,
1276 .canonicalise_fn
= ldif_canonicalise_objectCategory
,
1277 .comparison_fn
= ldif_comparison_objectCategory
,
1278 .operator_fn
= samba_syntax_operator_fn
1280 .name
= LDB_SYNTAX_SAMBA_SCHEMAINFO
,
1281 .ldif_read_fn
= ldb_handler_copy
,
1282 .ldif_write_fn
= ldif_write_schemaInfo
,
1283 .canonicalise_fn
= ldb_handler_copy
,
1284 .comparison_fn
= ldb_comparison_binary
,
1285 .operator_fn
= samba_syntax_operator_fn
1287 .name
= LDB_SYNTAX_SAMBA_PREFIX_MAP
,
1288 .ldif_read_fn
= ldif_read_prefixMap
,
1289 .ldif_write_fn
= ldif_write_prefixMap
,
1290 .canonicalise_fn
= ldif_canonicalise_prefixMap
,
1291 .comparison_fn
= ldif_comparison_prefixMap
,
1292 .operator_fn
= samba_syntax_operator_fn
1294 .name
= LDB_SYNTAX_SAMBA_INT32
,
1295 .ldif_read_fn
= ldb_handler_copy
,
1296 .ldif_write_fn
= ldb_handler_copy
,
1297 .canonicalise_fn
= ldif_canonicalise_int32
,
1298 .comparison_fn
= ldif_comparison_int32
,
1299 .operator_fn
= samba_syntax_operator_fn
1301 .name
= LDB_SYNTAX_SAMBA_REPSFROMTO
,
1302 .ldif_read_fn
= ldb_handler_copy
,
1303 .ldif_write_fn
= ldif_write_repsFromTo
,
1304 .canonicalise_fn
= ldb_handler_copy
,
1305 .comparison_fn
= ldb_comparison_binary
,
1306 .operator_fn
= samba_syntax_operator_fn
1308 .name
= LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA
,
1309 .ldif_read_fn
= ldb_handler_copy
,
1310 .ldif_write_fn
= ldif_write_replPropertyMetaData
,
1311 .canonicalise_fn
= ldb_handler_copy
,
1312 .comparison_fn
= ldb_comparison_binary
,
1313 .operator_fn
= samba_syntax_operator_fn
1315 .name
= LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR
,
1316 .ldif_read_fn
= ldb_handler_copy
,
1317 .ldif_write_fn
= ldif_write_replUpToDateVector
,
1318 .canonicalise_fn
= ldb_handler_copy
,
1319 .comparison_fn
= ldb_comparison_binary
,
1320 .operator_fn
= samba_syntax_operator_fn
1322 .name
= LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
,
1323 .ldif_read_fn
= ldb_handler_copy
,
1324 .ldif_write_fn
= ldif_write_trustAuthInOutBlob
,
1325 .canonicalise_fn
= ldb_handler_copy
,
1326 .comparison_fn
= ldb_comparison_binary
,
1327 .operator_fn
= samba_syntax_operator_fn
1329 .name
= DSDB_SYNTAX_BINARY_DN
,
1330 .ldif_read_fn
= ldb_handler_copy
,
1331 .ldif_write_fn
= ldb_handler_copy
,
1332 .canonicalise_fn
= dsdb_dn_binary_canonicalise
,
1333 .comparison_fn
= dsdb_dn_binary_comparison
,
1334 .operator_fn
= samba_syntax_operator_fn
1336 .name
= DSDB_SYNTAX_STRING_DN
,
1337 .ldif_read_fn
= ldb_handler_copy
,
1338 .ldif_write_fn
= ldb_handler_copy
,
1339 .canonicalise_fn
= dsdb_dn_string_canonicalise
,
1340 .comparison_fn
= dsdb_dn_string_comparison
,
1341 .operator_fn
= samba_syntax_operator_fn
1343 .name
= LDB_SYNTAX_DN
,
1344 .ldif_read_fn
= ldb_handler_copy
,
1345 .ldif_write_fn
= ldb_handler_copy
,
1346 .canonicalise_fn
= samba_ldb_dn_link_canonicalise
,
1347 .comparison_fn
= samba_ldb_dn_link_comparison
,
1348 .operator_fn
= samba_syntax_operator_dn
1350 .name
= LDB_SYNTAX_SAMBA_RANGE64
,
1351 .ldif_read_fn
= ldif_read_range64
,
1352 .ldif_write_fn
= ldif_write_range64
,
1353 .canonicalise_fn
= ldif_canonicalise_int64
,
1354 .comparison_fn
= ldif_comparison_int64
,
1355 .operator_fn
= samba_syntax_operator_fn
1357 .name
= LDB_SYNTAX_SAMBA_DNSRECORD
,
1358 .ldif_read_fn
= ldb_handler_copy
,
1359 .ldif_write_fn
= ldif_write_dnsRecord
,
1360 .canonicalise_fn
= ldb_handler_copy
,
1361 .comparison_fn
= ldb_comparison_binary
,
1362 .operator_fn
= samba_syntax_operator_fn
1364 .name
= LDB_SYNTAX_SAMBA_DNSPROPERTY
,
1365 .ldif_read_fn
= ldb_handler_copy
,
1366 .ldif_write_fn
= ldif_write_dnsProperty
,
1367 .canonicalise_fn
= ldb_handler_copy
,
1368 .comparison_fn
= ldb_comparison_binary
,
1369 .operator_fn
= samba_syntax_operator_fn
1371 .name
= LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS
,
1372 .ldif_read_fn
= ldb_handler_copy
,
1373 .ldif_write_fn
= ldif_write_supplementalCredentialsBlob
,
1374 .canonicalise_fn
= ldb_handler_copy
,
1375 .comparison_fn
= ldb_comparison_binary
,
1376 .operator_fn
= samba_syntax_operator_fn
1378 .name
= LDB_SYNTAX_SAMBA_PARTIALATTRIBUTESET
,
1379 .ldif_read_fn
= ldb_handler_copy
,
1380 .ldif_write_fn
= ldif_write_partialAttributeSet
,
1381 .canonicalise_fn
= ldb_handler_copy
,
1382 .comparison_fn
= ldb_comparison_binary
,
1383 .operator_fn
= samba_syntax_operator_fn
1387 static const struct ldb_dn_extended_syntax samba_dn_syntax
[] = {
1390 .read_fn
= extended_dn_read_SID
,
1391 .write_clear_fn
= ldif_write_objectSid
,
1392 .write_hex_fn
= extended_dn_write_hex
1395 .read_fn
= extended_dn_read_GUID
,
1396 .write_clear_fn
= ldif_write_objectGUID
,
1397 .write_hex_fn
= extended_dn_write_hex
1400 .read_fn
= ldb_handler_copy
,
1401 .write_clear_fn
= ldb_handler_copy
,
1402 .write_hex_fn
= ldb_handler_copy
1404 .name
= "RMD_INVOCID",
1405 .read_fn
= extended_dn_read_GUID
,
1406 .write_clear_fn
= ldif_write_objectGUID
,
1407 .write_hex_fn
= extended_dn_write_hex
1409 .name
= "RMD_FLAGS",
1410 .read_fn
= ldb_handler_copy
,
1411 .write_clear_fn
= ldb_handler_copy
,
1412 .write_hex_fn
= ldb_handler_copy
1414 .name
= "RMD_ADDTIME",
1415 .read_fn
= ldb_handler_copy
,
1416 .write_clear_fn
= ldb_handler_copy
,
1417 .write_hex_fn
= ldb_handler_copy
1419 .name
= "RMD_CHANGETIME",
1420 .read_fn
= ldb_handler_copy
,
1421 .write_clear_fn
= ldb_handler_copy
,
1422 .write_hex_fn
= ldb_handler_copy
1424 .name
= "RMD_LOCAL_USN",
1425 .read_fn
= ldb_handler_copy
,
1426 .write_clear_fn
= ldb_handler_copy
,
1427 .write_hex_fn
= ldb_handler_copy
1429 .name
= "RMD_ORIGINATING_USN",
1430 .read_fn
= ldb_handler_copy
,
1431 .write_clear_fn
= ldb_handler_copy
,
1432 .write_hex_fn
= ldb_handler_copy
1434 .name
= "RMD_VERSION",
1435 .read_fn
= ldb_handler_copy
,
1436 .write_clear_fn
= ldb_handler_copy
,
1437 .write_hex_fn
= ldb_handler_copy
1441 /* TODO: Should be dynamic at some point */
1442 static const struct {
1445 } samba_attributes
[] = {
1446 { "objectSid", LDB_SYNTAX_SAMBA_SID
},
1447 { "securityIdentifier", LDB_SYNTAX_SAMBA_SID
},
1448 { "tokenGroups", LDB_SYNTAX_SAMBA_SID
},
1449 { "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR
},
1450 { "oMSyntax", LDB_SYNTAX_SAMBA_INT32
},
1451 { "objectCategory", LDB_SYNTAX_SAMBA_OBJECT_CATEGORY
},
1452 { "schemaInfo", LDB_SYNTAX_SAMBA_SCHEMAINFO
},
1453 { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP
},
1454 { "repsFrom", LDB_SYNTAX_SAMBA_REPSFROMTO
},
1455 { "repsTo", LDB_SYNTAX_SAMBA_REPSFROMTO
},
1456 { "replPropertyMetaData", LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA
},
1457 { "replUpToDateVector", LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR
},
1458 { "trustAuthIncoming", LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
},
1459 { "trustAuthOutgoing", LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
},
1460 { "rIDAllocationPool", LDB_SYNTAX_SAMBA_RANGE64
},
1461 { "rIDPreviousAllocationPool", LDB_SYNTAX_SAMBA_RANGE64
},
1462 { "rIDAvailablePool", LDB_SYNTAX_SAMBA_RANGE64
},
1463 { "defaultSecurityDescriptor", LDB_SYNTAX_SAMBA_SDDL_SECURITY_DESCRIPTOR
},
1466 * these are extracted by searching
1467 * (&(attributeSyntax=2.5.5.10)(rangeLower=16)(rangeUpper=16)(omSyntax=4))
1469 { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID
},
1470 { "categoryId", LDB_SYNTAX_SAMBA_GUID
},
1471 { "controlAccessRights", LDB_SYNTAX_SAMBA_GUID
},
1472 { "currMachineId", LDB_SYNTAX_SAMBA_GUID
},
1473 { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID
},
1474 { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID
},
1475 { "implementedCategories", LDB_SYNTAX_SAMBA_GUID
},
1476 { "msDS-AzObjectGuid", LDB_SYNTAX_SAMBA_GUID
},
1477 { "msDFSR-ContentSetGuid", LDB_SYNTAX_SAMBA_GUID
},
1478 { "msDFSR-ReplicationGroupGuid", LDB_SYNTAX_SAMBA_GUID
},
1479 { "mSMQDigests", LDB_SYNTAX_SAMBA_GUID
},
1480 { "mSMQOwnerID", LDB_SYNTAX_SAMBA_GUID
},
1481 { "mSMQQMID", LDB_SYNTAX_SAMBA_GUID
},
1482 { "mSMQQueueType", LDB_SYNTAX_SAMBA_GUID
},
1483 { "mSMQSites", LDB_SYNTAX_SAMBA_GUID
},
1484 { "netbootGUID", LDB_SYNTAX_SAMBA_GUID
},
1485 { "objectGUID", LDB_SYNTAX_SAMBA_GUID
},
1486 { "pKTGuid", LDB_SYNTAX_SAMBA_GUID
},
1487 { "requiredCategories", LDB_SYNTAX_SAMBA_GUID
},
1488 { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID
},
1489 { "siteGUID", LDB_SYNTAX_SAMBA_GUID
},
1490 { "msDFS-GenerationGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1491 { "msDFS-LinkIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1492 { "msDFS-NamespaceIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1495 * these are known to be GUIDs
1497 { "invocationId", LDB_SYNTAX_SAMBA_GUID
},
1498 { "parentGUID", LDB_SYNTAX_SAMBA_GUID
},
1499 { "msDS-OptionalFeatureGUID", LDB_SYNTAX_SAMBA_GUID
},
1501 /* These NDR encoded things we want to be able to read with --show-binary */
1502 { "dnsRecord", LDB_SYNTAX_SAMBA_DNSRECORD
},
1503 { "dNSProperty", LDB_SYNTAX_SAMBA_DNSPROPERTY
},
1504 { "supplementalCredentials", LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS
},
1505 { "partialAttributeSet", LDB_SYNTAX_SAMBA_PARTIALATTRIBUTESET
}
1508 const struct ldb_schema_syntax
*ldb_samba_syntax_by_name(struct ldb_context
*ldb
, const char *name
)
1511 const struct ldb_schema_syntax
*s
= NULL
;
1513 for (j
=0; j
< ARRAY_SIZE(samba_syntaxes
); j
++) {
1514 if (strcmp(name
, samba_syntaxes
[j
].name
) == 0) {
1515 s
= &samba_syntaxes
[j
];
1522 const struct ldb_schema_syntax
*ldb_samba_syntax_by_lDAPDisplayName(struct ldb_context
*ldb
, const char *name
)
1525 const struct ldb_schema_syntax
*s
= NULL
;
1527 for (j
=0; j
< ARRAY_SIZE(samba_attributes
); j
++) {
1528 if (strcmp(samba_attributes
[j
].name
, name
) == 0) {
1529 s
= ldb_samba_syntax_by_name(ldb
, samba_attributes
[j
].syntax
);
1538 register the samba ldif handlers
1540 int ldb_register_samba_handlers(struct ldb_context
*ldb
)
1545 if (ldb_get_opaque(ldb
, "SAMBA_HANDLERS_REGISTERED") != NULL
) {
1549 for (i
=0; i
< ARRAY_SIZE(samba_attributes
); i
++) {
1550 const struct ldb_schema_syntax
*s
= NULL
;
1552 s
= ldb_samba_syntax_by_name(ldb
, samba_attributes
[i
].syntax
);
1555 s
= ldb_standard_syntax_by_name(ldb
, samba_attributes
[i
].syntax
);
1559 return LDB_ERR_OPERATIONS_ERROR
;
1562 ret
= ldb_schema_attribute_add_with_syntax(ldb
, samba_attributes
[i
].name
, LDB_ATTR_FLAG_FIXED
, s
);
1563 if (ret
!= LDB_SUCCESS
) {
1568 for (i
=0; i
< ARRAY_SIZE(samba_dn_syntax
); i
++) {
1569 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &samba_dn_syntax
[i
]);
1570 if (ret
!= LDB_SUCCESS
) {
1576 ret
= ldb_set_opaque(ldb
, "SAMBA_HANDLERS_REGISTERED", (void*)1);
1577 if (ret
!= LDB_SUCCESS
) {