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"
39 #include "lib/util/smb_strtox.h"
42 use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob
44 If mask_errors is true, then function succeeds but out data
45 is set to "<Unable to decode binary data>" message
47 \return 0 on success; -1 on error
49 static int ldif_write_NDR(struct ldb_context
*ldb
, void *mem_ctx
,
50 const struct ldb_val
*in
, struct ldb_val
*out
,
52 ndr_pull_flags_fn_t pull_fn
,
53 ndr_print_fn_t print_fn
,
57 enum ndr_err_code err
;
58 if (!(ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
)) {
59 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
61 p
= talloc_size(mem_ctx
, struct_size
);
62 err
= ndr_pull_struct_blob(in
, mem_ctx
,
64 if (err
!= NDR_ERR_SUCCESS
) {
65 /* fail in not in mask_error mode */
70 out
->data
= (uint8_t *)talloc_strdup(mem_ctx
, "<Unable to decode binary data>");
71 out
->length
= strlen((const char *)out
->data
);
74 out
->data
= (uint8_t *)ndr_print_struct_string(mem_ctx
, print_fn
, "NDR", p
);
76 if (out
->data
== NULL
) {
77 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
79 out
->length
= strlen((char *)out
->data
);
84 convert a ldif formatted objectSid to a NDR formatted blob
86 static int ldif_read_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
87 const struct ldb_val
*in
, struct ldb_val
*out
)
90 enum ndr_err_code ndr_err
;
92 if (in
->length
> DOM_SID_STR_BUFLEN
) {
95 if (in
->length
< 5) { /* "S-1-x" */
98 if (in
->data
[0] != 'S' && in
->data
[0] != 's') {
101 char p
[DOM_SID_STR_BUFLEN
+ 1];
102 memcpy(p
, in
->data
, in
->length
);
103 p
[in
->length
] = '\0';
105 ret
= dom_sid_parse(p
, &sid
);
110 *out
= data_blob_talloc(mem_ctx
, NULL
,
111 ndr_size_dom_sid(&sid
, 0));
112 if (out
->data
== NULL
) {
116 ndr_err
= ndr_push_struct_into_fixed_blob(out
, &sid
,
117 (ndr_push_flags_fn_t
)ndr_push_dom_sid
);
118 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
119 TALLOC_FREE(out
->data
);
127 convert a NDR formatted blob to a ldif formatted objectSid
129 int ldif_write_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
130 const struct ldb_val
*in
, struct ldb_val
*out
)
133 enum ndr_err_code ndr_err
;
135 ndr_err
= ndr_pull_struct_blob_all_noalloc(in
, &sid
,
136 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
137 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
140 *out
= data_blob_string_const(dom_sid_string(mem_ctx
, &sid
));
141 if (out
->data
== NULL
) {
148 compare two objectSids
150 If the SIDs seem to be strings, they are converted to binary form.
152 static int ldif_comparison_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
153 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
155 struct ldb_val parsed_1
= {.data
= NULL
};
156 struct ldb_val parsed_2
= {.data
= NULL
};
159 * If the ldb_vals look like SID strings (i.e. start with "S-"
160 * or "s-"), we treat them as strings.
162 * It is not really possible for a blob to be both a SID string and a
163 * SID struct -- the first two bytes of a struct dom_sid (including in
164 * NDR form) are the version (1), and the number of sub-auths (<= 15),
165 * neither of which are close to 'S' or '-'.
167 ret
= ldif_read_objectSid(ldb
, mem_ctx
, v1
, &parsed_1
);
171 ret
= ldif_read_objectSid(ldb
, mem_ctx
, v2
, &parsed_2
);
176 ret
= ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
178 TALLOC_FREE(parsed_1
.data
);
179 TALLOC_FREE(parsed_2
.data
);
184 canonicalise a objectSid
186 static int ldif_canonicalise_objectSid(struct ldb_context
*ldb
, void *mem_ctx
,
187 const struct ldb_val
*in
, struct ldb_val
*out
)
189 /* First try as a string SID */
190 if (ldif_read_objectSid(ldb
, mem_ctx
, in
, out
) == 0) {
193 /* not a string after all */
194 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
197 static int extended_dn_read_SID(struct ldb_context
*ldb
, void *mem_ctx
,
198 const struct ldb_val
*in
, struct ldb_val
*out
)
201 enum ndr_err_code ndr_err
;
203 if (ldif_read_objectSid(ldb
, mem_ctx
, in
, out
) == 0) {
207 /* Perhaps not a string after all */
208 *out
= data_blob_talloc(mem_ctx
, NULL
, in
->length
/2+1);
214 (*out
).length
= strhex_to_str((char *)out
->data
, out
->length
,
215 (const char *)in
->data
, in
->length
);
217 /* Check it looks like a SID */
218 ndr_err
= ndr_pull_struct_blob_all_noalloc(out
, &sid
,
219 (ndr_pull_flags_fn_t
)ndr_pull_dom_sid
);
220 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
221 TALLOC_FREE(out
->data
);
228 convert a ldif formatted objectGUID to a NDR formatted blob
230 static int ldif_read_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
231 const struct ldb_val
*in
, struct ldb_val
*out
)
236 status
= GUID_from_data_blob(in
, &guid
);
237 if (!NT_STATUS_IS_OK(status
)) {
241 status
= GUID_to_ndr_blob(&guid
, mem_ctx
, out
);
242 if (!NT_STATUS_IS_OK(status
)) {
249 convert a NDR formatted blob to a ldif formatted objectGUID
251 static int ldif_write_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
252 const struct ldb_val
*in
, struct ldb_val
*out
)
257 status
= GUID_from_ndr_blob(in
, &guid
);
258 if (!NT_STATUS_IS_OK(status
)) {
261 out
->data
= (uint8_t *)GUID_string(mem_ctx
, &guid
);
262 if (out
->data
== NULL
) {
265 out
->length
= strlen((const char *)out
->data
);
269 static bool ldif_comparision_objectGUID_isString(const struct ldb_val
*v
)
271 if (v
->length
!= 36 && v
->length
!= 38) return false;
273 /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */
277 static int extended_dn_read_GUID(struct ldb_context
*ldb
, void *mem_ctx
,
278 const struct ldb_val
*in
, struct ldb_val
*out
)
281 if (in
->length
== 36 && ldif_read_objectGUID(ldb
, mem_ctx
, in
, out
) == 0) {
285 /* Try as 'hex' form */
286 if (in
->length
!= 32) {
290 *out
= data_blob_talloc(mem_ctx
, NULL
, in
->length
/2+1);
296 (*out
).length
= strhex_to_str((char *)out
->data
, out
->length
,
297 (const char *)in
->data
, in
->length
);
299 /* Check it looks like a GUID */
300 if ((*out
).length
!= 16) {
309 compare two objectGUIDs
311 static int ldif_comparison_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
312 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
314 if (ldif_comparision_objectGUID_isString(v1
) && ldif_comparision_objectGUID_isString(v2
)) {
315 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
316 } else if (ldif_comparision_objectGUID_isString(v1
)
317 && !ldif_comparision_objectGUID_isString(v2
)) {
320 if (ldif_read_objectGUID(ldb
, mem_ctx
, v1
, &v
) != 0) {
321 /* Perhaps it wasn't a valid string after all */
322 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
324 ret
= ldb_comparison_binary(ldb
, mem_ctx
, &v
, v2
);
327 } else if (!ldif_comparision_objectGUID_isString(v1
)
328 && ldif_comparision_objectGUID_isString(v2
)) {
331 if (ldif_read_objectGUID(ldb
, mem_ctx
, v2
, &v
) != 0) {
332 /* Perhaps it wasn't a valid string after all */
333 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
335 ret
= ldb_comparison_binary(ldb
, mem_ctx
, v1
, &v
);
339 return ldb_comparison_binary(ldb
, mem_ctx
, v1
, v2
);
343 canonicalise a objectGUID
345 static int ldif_canonicalise_objectGUID(struct ldb_context
*ldb
, void *mem_ctx
,
346 const struct ldb_val
*in
, struct ldb_val
*out
)
348 if (ldif_comparision_objectGUID_isString(in
)) {
349 if (ldif_read_objectGUID(ldb
, mem_ctx
, in
, out
) != 0) {
350 /* Perhaps it wasn't a valid string after all */
351 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
355 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
360 convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob
362 static int ldif_read_ntSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
363 const struct ldb_val
*in
, struct ldb_val
*out
)
365 struct security_descriptor
*sd
;
366 enum ndr_err_code ndr_err
;
368 if (in
->length
>= 2 && isupper(in
->data
[0]) && in
->data
[1] == ':') {
370 * If it starts with an upper case character followed by ':',
371 * we know it's not NDR, but most likely SDDL...
373 const struct dom_sid
*sid
= samdb_domain_sid(ldb
);
375 sd
= sddl_decode(mem_ctx
, (const char *)in
->data
, sid
);
383 sd
= talloc(mem_ctx
, struct security_descriptor
);
388 ndr_err
= ndr_pull_struct_blob(in
, sd
, sd
,
389 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
390 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
396 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
, sd
,
397 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
);
399 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
407 convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format)
409 static int ldif_write_ntSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
410 const struct ldb_val
*in
, struct ldb_val
*out
)
412 struct security_descriptor
*sd
;
413 enum ndr_err_code ndr_err
;
415 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
416 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
417 sizeof(struct security_descriptor
),
418 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
,
419 (ndr_print_fn_t
)ndr_print_security_descriptor
,
424 sd
= talloc(mem_ctx
, struct security_descriptor
);
428 /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
429 ndr_err
= ndr_pull_struct_blob(in
, sd
, sd
,
430 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
431 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
435 out
->data
= (uint8_t *)sddl_encode(mem_ctx
, sd
, samdb_domain_sid_cache_only(ldb
));
437 if (out
->data
== NULL
) {
440 out
->length
= strlen((const char *)out
->data
);
445 convert a string formatted SDDL to a ldif formatted ntSecurityDescriptor (SDDL format)
447 static int ldif_write_sddlSecurityDescriptor(struct ldb_context
*ldb
, void *mem_ctx
,
448 const struct ldb_val
*in
, struct ldb_val
*out
)
450 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
451 struct security_descriptor
*sd
;
452 const struct dom_sid
*sid
= samdb_domain_sid(ldb
);
454 sd
= sddl_decode(mem_ctx
, (const char *)in
->data
, sid
);
455 out
->data
= (uint8_t *)ndr_print_struct_string(mem_ctx
,
456 (ndr_print_fn_t
)ndr_print_security_descriptor
,
458 out
->length
= strlen((const char *)out
->data
);
463 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
467 canonicalise an objectCategory. We use the long form as the canonical form:
468 'person' becomes cn=Person,cn=Schema,cn=Configuration,<basedn>
470 Also any short name of an objectClass that points to a different
471 class (such as user) has the canonical form of the class it's
472 defaultObjectCategory points to (eg
473 cn=Person,cn=Schema,cn=Configuration,<basedn>)
476 static int ldif_canonicalise_objectCategory(struct ldb_context
*ldb
, void *mem_ctx
,
477 const struct ldb_val
*in
, struct ldb_val
*out
)
479 struct ldb_dn
*dn1
= NULL
;
480 const struct dsdb_schema
*schema
= dsdb_get_schema(ldb
, NULL
);
481 const struct dsdb_class
*sclass
;
482 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
484 return LDB_ERR_OPERATIONS_ERROR
;
488 talloc_free(tmp_ctx
);
489 *out
= data_blob_talloc(mem_ctx
, in
->data
, in
->length
);
490 if (in
->data
&& !out
->data
) {
491 return LDB_ERR_OPERATIONS_ERROR
;
495 dn1
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, in
);
496 if ( ! ldb_dn_validate(dn1
)) {
497 const char *lDAPDisplayName
= talloc_strndup(tmp_ctx
, (char *)in
->data
, in
->length
);
498 sclass
= dsdb_class_by_lDAPDisplayName(schema
, lDAPDisplayName
);
500 struct ldb_dn
*dn
= ldb_dn_new(tmp_ctx
, ldb
,
501 sclass
->defaultObjectCategory
);
503 talloc_free(tmp_ctx
);
504 return LDB_ERR_OPERATIONS_ERROR
;
507 *out
= data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx
, dn
));
508 talloc_free(tmp_ctx
);
511 return LDB_ERR_OPERATIONS_ERROR
;
515 *out
= data_blob_talloc(mem_ctx
, in
->data
, in
->length
);
516 talloc_free(tmp_ctx
);
518 if (in
->data
&& !out
->data
) {
519 return LDB_ERR_OPERATIONS_ERROR
;
524 *out
= data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx
, dn1
));
525 talloc_free(tmp_ctx
);
528 return LDB_ERR_OPERATIONS_ERROR
;
533 static int ldif_comparison_objectCategory(struct ldb_context
*ldb
, void *mem_ctx
,
534 const struct ldb_val
*v1
,
535 const struct ldb_val
*v2
)
537 return ldb_any_comparison(ldb
, mem_ctx
, ldif_canonicalise_objectCategory
,
542 convert a NDR formatted blob to a ldif formatted schemaInfo
544 static int ldif_write_schemaInfo(struct ldb_context
*ldb
, void *mem_ctx
,
545 const struct ldb_val
*in
, struct ldb_val
*out
)
547 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
548 sizeof(struct schemaInfoBlob
),
549 (ndr_pull_flags_fn_t
)ndr_pull_schemaInfoBlob
,
550 (ndr_print_fn_t
)ndr_print_schemaInfoBlob
,
555 convert a ldif formatted prefixMap to a NDR formatted blob
557 static int ldif_read_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
558 const struct ldb_val
*in
, struct ldb_val
*out
)
560 struct prefixMapBlob
*blob
;
561 enum ndr_err_code ndr_err
;
562 char *string
, *line
, *p
, *oid
;
565 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
567 if (tmp_ctx
== NULL
) {
571 blob
= talloc_zero(tmp_ctx
, struct prefixMapBlob
);
573 talloc_free(tmp_ctx
);
577 /* use the switch value to detect if this is in the binary
580 if (in
->length
>= 4 && IVAL(in
->data
, 0) == PREFIX_MAP_VERSION_DSDB
) {
581 ndr_err
= ndr_pull_struct_blob(in
, tmp_ctx
, blob
,
582 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
);
583 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
584 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
,
586 (ndr_push_flags_fn_t
)ndr_push_prefixMapBlob
);
587 talloc_free(tmp_ctx
);
588 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
595 /* If this does not parse, then it is probably the text version, and we should try it that way */
596 blob
->version
= PREFIX_MAP_VERSION_DSDB
;
598 string
= talloc_strndup(mem_ctx
, (const char *)in
->data
, in
->length
);
599 if (string
== NULL
) {
605 while (line
&& line
[0]) {
612 p
=strchr(line
, '\n');
617 /* allow a trailing separator */
622 blob
->ctr
.dsdb
.mappings
= talloc_realloc(blob
,
623 blob
->ctr
.dsdb
.mappings
,
624 struct drsuapi_DsReplicaOIDMapping
,
625 blob
->ctr
.dsdb
.num_mappings
+1);
626 if (!blob
->ctr
.dsdb
.mappings
) {
627 talloc_free(tmp_ctx
);
631 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].id_prefix
=
632 smb_strtoul(line
, &oid
, 10, &error
, SMB_STR_STANDARD
);
634 if (oid
[0] != ':' || error
!= 0) {
635 talloc_free(tmp_ctx
);
639 /* we know there must be at least ":" */
642 if (!ber_write_partial_OID_String(blob
->ctr
.dsdb
.mappings
, &oid_blob
, oid
)) {
643 talloc_free(tmp_ctx
);
646 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].oid
.length
= oid_blob
.length
;
647 blob
->ctr
.dsdb
.mappings
[blob
->ctr
.dsdb
.num_mappings
].oid
.binary_oid
= oid_blob
.data
;
649 blob
->ctr
.dsdb
.num_mappings
++;
651 /* Now look past the terminator we added above */
659 ndr_err
= ndr_push_struct_blob(out
, mem_ctx
,
661 (ndr_push_flags_fn_t
)ndr_push_prefixMapBlob
);
662 talloc_free(tmp_ctx
);
663 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
670 convert a NDR formatted blob to a ldif formatted prefixMap
672 static int ldif_write_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
673 const struct ldb_val
*in
, struct ldb_val
*out
)
675 struct prefixMapBlob
*blob
;
676 enum ndr_err_code ndr_err
;
680 if (ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
) {
682 /* try to decode the blob as S4 prefixMap */
683 err
= ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
684 sizeof(struct prefixMapBlob
),
685 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
,
686 (ndr_print_fn_t
)ndr_print_prefixMapBlob
,
691 /* try parsing it as Windows PrefixMap value */
692 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
693 sizeof(struct drsuapi_MSPrefixMap_Ctr
),
694 (ndr_pull_flags_fn_t
)ndr_pull_drsuapi_MSPrefixMap_Ctr
,
695 (ndr_print_fn_t
)ndr_print_drsuapi_MSPrefixMap_Ctr
,
699 blob
= talloc(mem_ctx
, struct prefixMapBlob
);
703 ndr_err
= ndr_pull_struct_blob_all(in
, blob
,
705 (ndr_pull_flags_fn_t
)ndr_pull_prefixMapBlob
);
706 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
709 if (blob
->version
!= PREFIX_MAP_VERSION_DSDB
) {
712 string
= talloc_strdup(mem_ctx
, "");
713 if (string
== NULL
) {
717 for (i
=0; i
< blob
->ctr
.dsdb
.num_mappings
; i
++) {
719 char *partial_oid
= NULL
;
722 talloc_asprintf_addbuf(&string
, ";");
725 oid_blob
= data_blob_const(blob
->ctr
.dsdb
.mappings
[i
].oid
.binary_oid
,
726 blob
->ctr
.dsdb
.mappings
[i
].oid
.length
);
727 if (!ber_read_partial_OID_String(blob
, oid_blob
, &partial_oid
)) {
728 DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X\n",
729 blob
->ctr
.dsdb
.mappings
[i
].id_prefix
));
732 talloc_asprintf_addbuf(&string
, "%u:%s",
733 blob
->ctr
.dsdb
.mappings
[i
].id_prefix
,
735 talloc_free(discard_const(partial_oid
));
739 *out
= data_blob_string_const(string
);
747 static bool ldif_comparision_prefixMap_isString(const struct ldb_val
*v
)
753 if (IVAL(v
->data
, 0) == PREFIX_MAP_VERSION_DSDB
) {
761 canonicalise a prefixMap
763 static int ldif_canonicalise_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
764 const struct ldb_val
*in
, struct ldb_val
*out
)
766 if (ldif_comparision_prefixMap_isString(in
)) {
767 return ldif_read_prefixMap(ldb
, mem_ctx
, in
, out
);
769 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
772 static int ldif_comparison_prefixMap(struct ldb_context
*ldb
, void *mem_ctx
,
773 const struct ldb_val
*v1
,
774 const struct ldb_val
*v2
)
776 return ldb_any_comparison(ldb
, mem_ctx
, ldif_canonicalise_prefixMap
,
780 /* length limited conversion of a ldb_val to a int32_t */
781 static int val_to_int32(const struct ldb_val
*in
, int32_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 /* We've to use "strtoll" here to have the intended overflows.
794 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
795 *v
= (int32_t) strtoll(buf
, &end
, 0);
797 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
802 /* length limited conversion of a ldb_val to a int64_t */
803 static int val_to_int64(const struct ldb_val
*in
, int64_t *v
)
808 /* make sure we don't read past the end of the data */
809 if (in
->length
> sizeof(buf
)-1) {
810 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
812 strncpy(buf
, (char *)in
->data
, in
->length
);
815 *v
= (int64_t) strtoll(buf
, &end
, 0);
817 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
822 /* Canonicalisation of two 32-bit integers */
823 static int ldif_canonicalise_int32(struct ldb_context
*ldb
, void *mem_ctx
,
824 const struct ldb_val
*in
, struct ldb_val
*out
)
829 ret
= val_to_int32(in
, &i
);
830 if (ret
!= LDB_SUCCESS
) {
833 out
->data
= (uint8_t *) talloc_asprintf(mem_ctx
, "%d", i
);
834 if (out
->data
== NULL
) {
836 return LDB_ERR_OPERATIONS_ERROR
;
838 out
->length
= strlen((char *)out
->data
);
843 * Lexicographically sorted representation for a 32-bit integer
845 * [ INT32_MIN ... -3, -2, -1 | 0 | +1, +2, +3 ... INT32_MAX ]
848 * Refer to the comment in lib/ldb/common/attrib_handlers.c for the
849 * corresponding documentation for 64-bit integers.
851 * The same rules apply but use INT32_MIN and INT32_MAX.
853 * String representation padding is done to 10 characters.
855 * INT32_MAX = 2^31 - 1 = 2147483647 (10 characters long)
858 static int ldif_index_format_int32(struct ldb_context
*ldb
,
860 const struct ldb_val
*in
,
868 ret
= val_to_int32(in
, &i
);
869 if (ret
!= LDB_SUCCESS
) {
875 * i is negative, so this is subtraction rather than
879 i
= INT32_MAX
+ i
+ 1;
886 out
->data
= (uint8_t *) talloc_asprintf(mem_ctx
, "%c%010ld", prefix
, (long)i
);
887 if (out
->data
== NULL
) {
889 return LDB_ERR_OPERATIONS_ERROR
;
892 len
= talloc_array_length(out
->data
) - 1;
894 ldb_debug(ldb
, LDB_DEBUG_ERROR
,
895 __location__
": expected index format str %s to"
896 " have length 11 but got %zu",
897 (char*)out
->data
, len
);
898 return LDB_ERR_OPERATIONS_ERROR
;
905 /* Comparison of two 32-bit integers */
906 static int ldif_comparison_int32(struct ldb_context
*ldb
, void *mem_ctx
,
907 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
910 val_to_int32(v1
, &i1
);
911 val_to_int32(v2
, &i2
);
912 if (i1
== i2
) return 0;
913 return i1
> i2
? 1 : -1;
916 /* Canonicalisation of two 64-bit integers */
917 static int ldif_canonicalise_int64(struct ldb_context
*ldb
, void *mem_ctx
,
918 const struct ldb_val
*in
, struct ldb_val
*out
)
923 ret
= val_to_int64(in
, &i
);
924 if (ret
!= LDB_SUCCESS
) {
927 out
->data
= (uint8_t *) talloc_asprintf(mem_ctx
, "%lld", (long long)i
);
928 if (out
->data
== NULL
) {
930 return LDB_ERR_OPERATIONS_ERROR
;
932 out
->length
= strlen((char *)out
->data
);
936 /* Comparison of two 64-bit integers */
937 static int ldif_comparison_int64(struct ldb_context
*ldb
, void *mem_ctx
,
938 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
941 val_to_int64(v1
, &i1
);
942 val_to_int64(v2
, &i2
);
943 if (i1
== i2
) return 0;
944 return i1
> i2
? 1 : -1;
948 convert a NDR formatted blob to a ldif formatted repsFromTo
950 static int ldif_write_repsFromTo(struct ldb_context
*ldb
, void *mem_ctx
,
951 const struct ldb_val
*in
, struct ldb_val
*out
)
953 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
954 sizeof(struct repsFromToBlob
),
955 (ndr_pull_flags_fn_t
)ndr_pull_repsFromToBlob
,
956 (ndr_print_fn_t
)ndr_print_repsFromToBlob
,
961 convert a NDR formatted blob to a ldif formatted replPropertyMetaData
963 static int ldif_write_replPropertyMetaData(struct ldb_context
*ldb
, void *mem_ctx
,
964 const struct ldb_val
*in
, struct ldb_val
*out
)
966 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
967 sizeof(struct replPropertyMetaDataBlob
),
968 (ndr_pull_flags_fn_t
)ndr_pull_replPropertyMetaDataBlob
,
969 (ndr_print_fn_t
)ndr_print_replPropertyMetaDataBlob
,
974 convert a NDR formatted blob to a ldif formatted replUpToDateVector
976 static int ldif_write_replUpToDateVector(struct ldb_context
*ldb
, void *mem_ctx
,
977 const struct ldb_val
*in
, struct ldb_val
*out
)
979 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
980 sizeof(struct replUpToDateVectorBlob
),
981 (ndr_pull_flags_fn_t
)ndr_pull_replUpToDateVectorBlob
,
982 (ndr_print_fn_t
)ndr_print_replUpToDateVectorBlob
,
986 static int ldif_write_dn_binary_NDR(struct ldb_context
*ldb
, void *mem_ctx
,
987 const struct ldb_val
*in
, struct ldb_val
*out
,
989 ndr_pull_flags_fn_t pull_fn
,
990 ndr_print_fn_t print_fn
,
994 enum ndr_err_code err
;
995 struct dsdb_dn
*dsdb_dn
= NULL
;
999 if (!(ldb_get_flags(ldb
) & LDB_FLG_SHOW_BINARY
)) {
1000 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1003 dsdb_dn
= dsdb_dn_parse(mem_ctx
, ldb
, in
, DSDB_SYNTAX_BINARY_DN
);
1004 if (dsdb_dn
== NULL
) {
1005 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1008 p
= talloc_size(dsdb_dn
, struct_size
);
1010 TALLOC_FREE(dsdb_dn
);
1011 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1014 err
= ndr_pull_struct_blob(&dsdb_dn
->extra_part
, p
, p
, pull_fn
);
1015 if (err
!= NDR_ERR_SUCCESS
) {
1016 /* fail in not in mask_error mode */
1020 TALLOC_FREE(dsdb_dn
);
1021 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1024 dn_str
= ldb_dn_get_extended_linearized(dsdb_dn
, dsdb_dn
->dn
, 1);
1025 if (dn_str
== NULL
) {
1026 TALLOC_FREE(dsdb_dn
);
1027 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1030 str
= ndr_print_struct_string(mem_ctx
, print_fn
, dn_str
, p
);
1031 TALLOC_FREE(dsdb_dn
);
1033 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1036 *out
= data_blob_string_const(str
);
1040 static int ldif_write_msDS_RevealedUsers(struct ldb_context
*ldb
, void *mem_ctx
,
1041 const struct ldb_val
*in
, struct ldb_val
*out
)
1043 return ldif_write_dn_binary_NDR(ldb
, mem_ctx
, in
, out
,
1044 sizeof(struct replPropertyMetaData1
),
1045 (ndr_pull_flags_fn_t
)ndr_pull_replPropertyMetaData1
,
1046 (ndr_print_fn_t
)ndr_print_replPropertyMetaData1
,
1051 convert a NDR formatted blob to a ldif formatted dnsRecord
1053 static int ldif_write_dnsRecord(struct ldb_context
*ldb
, void *mem_ctx
,
1054 const struct ldb_val
*in
, struct ldb_val
*out
)
1056 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1057 sizeof(struct dnsp_DnssrvRpcRecord
),
1058 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnssrvRpcRecord
,
1059 (ndr_print_fn_t
)ndr_print_dnsp_DnssrvRpcRecord
,
1064 convert a NDR formatted blob to a ldif formatted dnsProperty
1066 static int ldif_write_dnsProperty(struct ldb_context
*ldb
, void *mem_ctx
,
1067 const struct ldb_val
*in
, struct ldb_val
*out
)
1069 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1070 sizeof(struct dnsp_DnsProperty
),
1071 (ndr_pull_flags_fn_t
)ndr_pull_dnsp_DnsProperty
,
1072 (ndr_print_fn_t
)ndr_print_dnsp_DnsProperty
,
1077 convert a NDR formatted blob of a supplementalCredentials into text
1079 static int ldif_write_supplementalCredentialsBlob(struct ldb_context
*ldb
, void *mem_ctx
,
1080 const struct ldb_val
*in
, struct ldb_val
*out
)
1082 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1083 sizeof(struct supplementalCredentialsBlob
),
1084 (ndr_pull_flags_fn_t
)ndr_pull_supplementalCredentialsBlob
,
1085 (ndr_print_fn_t
)ndr_print_supplementalCredentialsBlob
,
1090 convert a NDR formatted blob to a ldif formatted trustAuthInOutBlob
1092 static int ldif_write_trustAuthInOutBlob(struct ldb_context
*ldb
, void *mem_ctx
,
1093 const struct ldb_val
*in
, struct ldb_val
*out
)
1095 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1096 sizeof(struct trustAuthInOutBlob
),
1097 (ndr_pull_flags_fn_t
)ndr_pull_trustAuthInOutBlob
,
1098 (ndr_print_fn_t
)ndr_print_trustAuthInOutBlob
,
1103 convert a NDR formatted blob to a ldif formatted msDS-TrustForestTrustInfo
1105 static int ldif_write_ForestTrustInfo(struct ldb_context
*ldb
, void *mem_ctx
,
1106 const struct ldb_val
*in
, struct ldb_val
*out
)
1108 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1109 sizeof(struct ForestTrustInfo
),
1110 (ndr_pull_flags_fn_t
)ndr_pull_ForestTrustInfo
,
1111 (ndr_print_fn_t
)ndr_print_ForestTrustInfo
,
1115 convert a NDR formatted blob of a partialAttributeSet into text
1117 static int ldif_write_partialAttributeSet(struct ldb_context
*ldb
, void *mem_ctx
,
1118 const struct ldb_val
*in
, struct ldb_val
*out
)
1120 return ldif_write_NDR(ldb
, mem_ctx
, in
, out
,
1121 sizeof(struct partialAttributeSetBlob
),
1122 (ndr_pull_flags_fn_t
)ndr_pull_partialAttributeSetBlob
,
1123 (ndr_print_fn_t
)ndr_print_partialAttributeSetBlob
,
1128 static int extended_dn_write_hex(struct ldb_context
*ldb
, void *mem_ctx
,
1129 const struct ldb_val
*in
, struct ldb_val
*out
)
1131 *out
= data_blob_string_const(data_blob_hex_string_lower(mem_ctx
, in
));
1141 static int samba_ldb_dn_link_comparison(struct ldb_context
*ldb
, void *mem_ctx
,
1142 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
1144 struct ldb_dn
*dn1
= NULL
, *dn2
= NULL
;
1148 * In a sort context, Deleted DNs get shifted to the end.
1149 * They never match in an equality
1151 if (dsdb_dn_is_deleted_val(v1
)) {
1152 if (! dsdb_dn_is_deleted_val(v2
)) {
1156 * They are both deleted!
1158 * The soundest thing to do at this point is carry on
1159 * and compare the DNs normally. This matches the
1160 * behaviour of samba_dn_extended_match() below.
1162 } else if (dsdb_dn_is_deleted_val(v2
)) {
1166 dn1
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, v1
);
1167 dn2
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, v2
);
1169 if ( ! ldb_dn_validate(dn1
)) {
1171 if ( ! ldb_dn_validate(dn2
)) {
1179 if ( ! ldb_dn_validate(dn2
)) {
1185 ret
= ldb_dn_compare(dn1
, dn2
);
1192 static int samba_ldb_dn_link_canonicalise(struct ldb_context
*ldb
, void *mem_ctx
,
1193 const struct ldb_val
*in
, struct ldb_val
*out
)
1201 dn
= ldb_dn_from_ldb_val(mem_ctx
, ldb
, in
);
1202 if ( ! ldb_dn_validate(dn
)) {
1203 return LDB_ERR_INVALID_DN_SYNTAX
;
1206 /* By including the RMD_FLAGS of a deleted DN, we ensure it
1207 * does not casually match a not deleted DN */
1208 if (dsdb_dn_is_deleted_val(in
)) {
1209 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
,
1211 dsdb_dn_val_rmd_flags(in
),
1212 ldb_dn_get_casefold(dn
));
1214 out
->data
= (uint8_t *)ldb_dn_alloc_casefold(mem_ctx
, dn
);
1217 if (out
->data
== NULL
) {
1220 out
->length
= strlen((char *)out
->data
);
1232 write a 64 bit 2-part range
1234 static int ldif_write_range64(struct ldb_context
*ldb
, void *mem_ctx
,
1235 const struct ldb_val
*in
, struct ldb_val
*out
)
1239 ret
= val_to_int64(in
, &v
);
1240 if (ret
!= LDB_SUCCESS
) {
1243 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
, "%lu-%lu",
1244 (unsigned long)(v
&0xFFFFFFFF),
1245 (unsigned long)(v
>>32));
1246 if (out
->data
== NULL
) {
1248 return LDB_ERR_OPERATIONS_ERROR
;
1250 out
->length
= strlen((char *)out
->data
);
1255 read a 64 bit 2-part range
1257 static int ldif_read_range64(struct ldb_context
*ldb
, void *mem_ctx
,
1258 const struct ldb_val
*in
, struct ldb_val
*out
)
1260 unsigned long high
, low
;
1263 if (memchr(in
->data
, '-', in
->length
) == NULL
) {
1264 return ldb_handler_copy(ldb
, mem_ctx
, in
, out
);
1267 if (in
->length
> sizeof(buf
)-1) {
1268 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
1270 strncpy(buf
, (const char *)in
->data
, in
->length
);
1271 buf
[in
->length
] = 0;
1273 if (sscanf(buf
, "%lu-%lu", &low
, &high
) != 2) {
1274 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX
;
1277 out
->data
= (uint8_t *)talloc_asprintf(mem_ctx
, "%llu",
1278 (unsigned long long)(((uint64_t)high
)<<32) | (low
));
1280 if (out
->data
== NULL
) {
1282 return LDB_ERR_OPERATIONS_ERROR
;
1284 out
->length
= strlen((char *)out
->data
);
1289 when this operator_fn is set for a syntax, the backend calls is in
1290 preference to the comparison function. We are told the exact
1291 comparison operation that is needed, and we can return errors
1293 static int samba_syntax_operator_fn(struct ldb_context
*ldb
, enum ldb_parse_op operation
,
1294 const struct ldb_schema_attribute
*a
,
1295 const struct ldb_val
*v1
, const struct ldb_val
*v2
, bool *matched
)
1297 switch (operation
) {
1301 case LDB_OP_SUBSTRING
:
1303 case LDB_OP_EXTENDED
:
1304 /* handled in the backends */
1305 return LDB_ERR_INAPPROPRIATE_MATCHING
;
1307 case LDB_OP_GREATER
:
1309 case LDB_OP_EQUALITY
:
1311 TALLOC_CTX
*tmp_ctx
= talloc_new(ldb
);
1313 if (tmp_ctx
== NULL
) {
1314 return ldb_oom(ldb
);
1316 ret
= a
->syntax
->comparison_fn(ldb
, tmp_ctx
, v1
, v2
);
1317 talloc_free(tmp_ctx
);
1318 if (operation
== LDB_OP_GREATER
) {
1319 *matched
= (ret
>= 0);
1320 } else if (operation
== LDB_OP_LESS
) {
1321 *matched
= (ret
<= 0);
1323 *matched
= (ret
== 0);
1328 case LDB_OP_PRESENT
:
1333 /* we shouldn't get here */
1334 return LDB_ERR_INAPPROPRIATE_MATCHING
;
1338 compare two binary objects. This is correct for sorting as the sort order is:
1345 rather than ldb_comparison_binary() which is:
1353 static int samba_ldb_comparison_binary(struct ldb_context
*ldb
, void *mem_ctx
,
1354 const struct ldb_val
*v1
, const struct ldb_val
*v2
)
1356 return data_blob_cmp(v1
, v2
);
1360 when this operator_fn is set for a syntax, the backend calls is in
1361 preference to the comparison function. We are told the exact
1362 comparison operation that is needed, and we can return errors.
1364 This mode optimises for ldb_comparison_binary() if we need equality,
1365 as this should be faster as it can do a length-check first.
1367 static int samba_syntax_binary_operator_fn(struct ldb_context
*ldb
, enum ldb_parse_op operation
,
1368 const struct ldb_schema_attribute
*a
,
1369 const struct ldb_val
*v1
, const struct ldb_val
*v2
, bool *matched
)
1371 if (operation
== LDB_OP_EQUALITY
) {
1372 *matched
= (ldb_comparison_binary(ldb
, NULL
, v1
, v2
) == 0);
1375 return samba_syntax_operator_fn(ldb
, operation
, a
, v1
, v2
, matched
);
1379 see if two DNs match, comparing first by GUID, then by SID, and
1380 finally by string components
1382 static int samba_dn_extended_match(struct ldb_context
*ldb
,
1383 const struct ldb_val
*v1
,
1384 const struct ldb_val
*v2
,
1387 TALLOC_CTX
*tmp_ctx
;
1388 struct ldb_dn
*dn1
, *dn2
;
1389 const struct ldb_val
*guid1
, *guid2
, *sid1
, *sid2
;
1390 uint32_t rmd_flags1
, rmd_flags2
;
1392 tmp_ctx
= talloc_new(ldb
);
1394 dn1
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, v1
);
1395 dn2
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, v2
);
1397 /* couldn't parse as DN's */
1398 talloc_free(tmp_ctx
);
1403 rmd_flags1
= dsdb_dn_rmd_flags(dn1
);
1404 rmd_flags2
= dsdb_dn_rmd_flags(dn2
);
1406 if ((rmd_flags1
& DSDB_RMD_FLAG_DELETED
) !=
1407 (rmd_flags2
& DSDB_RMD_FLAG_DELETED
)) {
1408 /* only match if they have the same deletion status */
1409 talloc_free(tmp_ctx
);
1415 guid1
= ldb_dn_get_extended_component(dn1
, "GUID");
1416 guid2
= ldb_dn_get_extended_component(dn2
, "GUID");
1417 if (guid1
&& guid2
) {
1418 (*matched
) = (data_blob_cmp(guid1
, guid2
) == 0);
1419 talloc_free(tmp_ctx
);
1423 sid1
= ldb_dn_get_extended_component(dn1
, "SID");
1424 sid2
= ldb_dn_get_extended_component(dn2
, "SID");
1426 (*matched
) = (data_blob_cmp(sid1
, sid2
) == 0);
1427 talloc_free(tmp_ctx
);
1431 (*matched
) = (ldb_dn_compare(dn1
, dn2
) == 0);
1433 talloc_free(tmp_ctx
);
1438 special operation for DNs, to take account of the RMD_FLAGS deleted bit
1440 static int samba_syntax_operator_dn(struct ldb_context
*ldb
, enum ldb_parse_op operation
,
1441 const struct ldb_schema_attribute
*a
,
1442 const struct ldb_val
*v1
, const struct ldb_val
*v2
, bool *matched
)
1444 if (operation
== LDB_OP_PRESENT
&& dsdb_dn_is_deleted_val(v1
)) {
1445 /* If the DN is deleted, then we can't search for it */
1447 /* should this be for equality too? */
1452 if (operation
== LDB_OP_EQUALITY
&&
1453 samba_dn_extended_match(ldb
, v1
, v2
, matched
) == LDB_SUCCESS
) {
1457 return samba_syntax_operator_fn(ldb
, operation
, a
, v1
, v2
, matched
);
1461 static const struct ldb_schema_syntax samba_syntaxes
[] = {
1463 .name
= LDB_SYNTAX_SAMBA_SID
,
1464 .ldif_read_fn
= ldif_read_objectSid
,
1465 .ldif_write_fn
= ldif_write_objectSid
,
1466 .canonicalise_fn
= ldif_canonicalise_objectSid
,
1467 .comparison_fn
= ldif_comparison_objectSid
,
1468 .operator_fn
= samba_syntax_operator_fn
1470 .name
= LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR
,
1471 .ldif_read_fn
= ldif_read_ntSecurityDescriptor
,
1472 .ldif_write_fn
= ldif_write_ntSecurityDescriptor
,
1473 .canonicalise_fn
= ldb_handler_copy
,
1474 .comparison_fn
= samba_ldb_comparison_binary
,
1475 .operator_fn
= samba_syntax_binary_operator_fn
1477 .name
= LDB_SYNTAX_SAMBA_SDDL_SECURITY_DESCRIPTOR
,
1478 .ldif_read_fn
= ldb_handler_copy
,
1479 .ldif_write_fn
= ldif_write_sddlSecurityDescriptor
,
1480 .canonicalise_fn
= ldb_handler_fold
,
1481 .comparison_fn
= ldb_comparison_fold
,
1482 .operator_fn
= samba_syntax_operator_fn
1484 .name
= LDB_SYNTAX_SAMBA_GUID
,
1485 .ldif_read_fn
= ldif_read_objectGUID
,
1486 .ldif_write_fn
= ldif_write_objectGUID
,
1487 .canonicalise_fn
= ldif_canonicalise_objectGUID
,
1488 .comparison_fn
= ldif_comparison_objectGUID
,
1489 .operator_fn
= samba_syntax_operator_fn
1491 .name
= LDB_SYNTAX_SAMBA_OBJECT_CATEGORY
,
1492 .ldif_read_fn
= ldb_handler_copy
,
1493 .ldif_write_fn
= ldb_handler_copy
,
1494 .canonicalise_fn
= ldif_canonicalise_objectCategory
,
1495 .comparison_fn
= ldif_comparison_objectCategory
,
1496 .operator_fn
= samba_syntax_operator_fn
1498 .name
= LDB_SYNTAX_SAMBA_SCHEMAINFO
,
1499 .ldif_read_fn
= ldb_handler_copy
,
1500 .ldif_write_fn
= ldif_write_schemaInfo
,
1501 .canonicalise_fn
= ldb_handler_copy
,
1502 .comparison_fn
= samba_ldb_comparison_binary
,
1503 .operator_fn
= samba_syntax_binary_operator_fn
1505 .name
= LDB_SYNTAX_SAMBA_PREFIX_MAP
,
1506 .ldif_read_fn
= ldif_read_prefixMap
,
1507 .ldif_write_fn
= ldif_write_prefixMap
,
1508 .canonicalise_fn
= ldif_canonicalise_prefixMap
,
1509 .comparison_fn
= ldif_comparison_prefixMap
,
1510 .operator_fn
= samba_syntax_operator_fn
1512 .name
= LDB_SYNTAX_SAMBA_INT32
,
1513 .ldif_read_fn
= ldb_handler_copy
,
1514 .ldif_write_fn
= ldb_handler_copy
,
1515 .canonicalise_fn
= ldif_canonicalise_int32
,
1516 .index_format_fn
= ldif_index_format_int32
,
1517 .comparison_fn
= ldif_comparison_int32
,
1518 .operator_fn
= samba_syntax_operator_fn
1520 .name
= LDB_SYNTAX_SAMBA_REPSFROMTO
,
1521 .ldif_read_fn
= ldb_handler_copy
,
1522 .ldif_write_fn
= ldif_write_repsFromTo
,
1523 .canonicalise_fn
= ldb_handler_copy
,
1524 .comparison_fn
= samba_ldb_comparison_binary
,
1525 .operator_fn
= samba_syntax_binary_operator_fn
1527 .name
= LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA
,
1528 .ldif_read_fn
= ldb_handler_copy
,
1529 .ldif_write_fn
= ldif_write_replPropertyMetaData
,
1530 .canonicalise_fn
= ldb_handler_copy
,
1531 .comparison_fn
= samba_ldb_comparison_binary
,
1532 .operator_fn
= samba_syntax_binary_operator_fn
1534 .name
= LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR
,
1535 .ldif_read_fn
= ldb_handler_copy
,
1536 .ldif_write_fn
= ldif_write_replUpToDateVector
,
1537 .canonicalise_fn
= ldb_handler_copy
,
1538 .comparison_fn
= samba_ldb_comparison_binary
,
1539 .operator_fn
= samba_syntax_binary_operator_fn
1541 .name
= LDB_SYNTAX_SAMBA_REVEALEDUSERS
,
1542 .ldif_read_fn
= ldb_handler_copy
,
1543 .ldif_write_fn
= ldif_write_msDS_RevealedUsers
,
1544 .canonicalise_fn
= dsdb_dn_binary_canonicalise
,
1545 .comparison_fn
= dsdb_dn_binary_comparison
,
1546 .operator_fn
= samba_syntax_operator_fn
1548 .name
= LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
,
1549 .ldif_read_fn
= ldb_handler_copy
,
1550 .ldif_write_fn
= ldif_write_trustAuthInOutBlob
,
1551 .canonicalise_fn
= ldb_handler_copy
,
1552 .comparison_fn
= samba_ldb_comparison_binary
,
1553 .operator_fn
= samba_syntax_binary_operator_fn
1555 .name
= LDB_SYNTAX_SAMBA_FORESTTRUSTINFO
,
1556 .ldif_read_fn
= ldb_handler_copy
,
1557 .ldif_write_fn
= ldif_write_ForestTrustInfo
,
1558 .canonicalise_fn
= ldb_handler_copy
,
1559 .comparison_fn
= samba_ldb_comparison_binary
,
1560 .operator_fn
= samba_syntax_binary_operator_fn
1562 .name
= DSDB_SYNTAX_BINARY_DN
,
1563 .ldif_read_fn
= ldb_handler_copy
,
1564 .ldif_write_fn
= ldb_handler_copy
,
1565 .canonicalise_fn
= dsdb_dn_binary_canonicalise
,
1566 .comparison_fn
= dsdb_dn_binary_comparison
,
1567 .operator_fn
= samba_syntax_operator_fn
1569 .name
= DSDB_SYNTAX_STRING_DN
,
1570 .ldif_read_fn
= ldb_handler_copy
,
1571 .ldif_write_fn
= ldb_handler_copy
,
1572 .canonicalise_fn
= dsdb_dn_string_canonicalise
,
1573 .comparison_fn
= dsdb_dn_string_comparison
,
1574 .operator_fn
= samba_syntax_operator_fn
1576 .name
= LDB_SYNTAX_DN
,
1577 .ldif_read_fn
= ldb_handler_copy
,
1578 .ldif_write_fn
= ldb_handler_copy
,
1579 .canonicalise_fn
= samba_ldb_dn_link_canonicalise
,
1580 .comparison_fn
= samba_ldb_dn_link_comparison
,
1581 .operator_fn
= samba_syntax_operator_dn
1583 .name
= LDB_SYNTAX_SAMBA_RANGE64
,
1584 .ldif_read_fn
= ldif_read_range64
,
1585 .ldif_write_fn
= ldif_write_range64
,
1586 .canonicalise_fn
= ldif_canonicalise_int64
,
1587 .comparison_fn
= ldif_comparison_int64
,
1588 .operator_fn
= samba_syntax_operator_fn
1590 .name
= LDB_SYNTAX_SAMBA_DNSRECORD
,
1591 .ldif_read_fn
= ldb_handler_copy
,
1592 .ldif_write_fn
= ldif_write_dnsRecord
,
1593 .canonicalise_fn
= ldb_handler_copy
,
1594 .comparison_fn
= samba_ldb_comparison_binary
,
1595 .operator_fn
= samba_syntax_binary_operator_fn
1597 .name
= LDB_SYNTAX_SAMBA_DNSPROPERTY
,
1598 .ldif_read_fn
= ldb_handler_copy
,
1599 .ldif_write_fn
= ldif_write_dnsProperty
,
1600 .canonicalise_fn
= ldb_handler_copy
,
1601 .comparison_fn
= samba_ldb_comparison_binary
,
1602 .operator_fn
= samba_syntax_binary_operator_fn
1604 .name
= LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS
,
1605 .ldif_read_fn
= ldb_handler_copy
,
1606 .ldif_write_fn
= ldif_write_supplementalCredentialsBlob
,
1607 .canonicalise_fn
= ldb_handler_copy
,
1608 .comparison_fn
= samba_ldb_comparison_binary
,
1609 .operator_fn
= samba_syntax_binary_operator_fn
1611 .name
= LDB_SYNTAX_SAMBA_PARTIALATTRIBUTESET
,
1612 .ldif_read_fn
= ldb_handler_copy
,
1613 .ldif_write_fn
= ldif_write_partialAttributeSet
,
1614 .canonicalise_fn
= ldb_handler_copy
,
1615 .comparison_fn
= samba_ldb_comparison_binary
,
1616 .operator_fn
= samba_syntax_binary_operator_fn
1618 .name
= LDB_SYNTAX_SAMBA_OCTET_STRING
,
1619 .ldif_read_fn
= ldb_handler_copy
,
1620 .ldif_write_fn
= ldb_handler_copy
,
1621 .canonicalise_fn
= ldb_handler_copy
,
1622 .comparison_fn
= samba_ldb_comparison_binary
,
1623 .operator_fn
= samba_syntax_binary_operator_fn
1627 static const struct ldb_dn_extended_syntax samba_dn_syntax
[] = {
1630 .read_fn
= extended_dn_read_SID
,
1631 .write_clear_fn
= ldif_write_objectSid
,
1632 .write_hex_fn
= extended_dn_write_hex
1635 .read_fn
= extended_dn_read_GUID
,
1636 .write_clear_fn
= ldif_write_objectGUID
,
1637 .write_hex_fn
= extended_dn_write_hex
1640 .read_fn
= ldb_handler_copy
,
1641 .write_clear_fn
= ldb_handler_copy
,
1642 .write_hex_fn
= ldb_handler_copy
1644 .name
= "RMD_INVOCID",
1645 .read_fn
= extended_dn_read_GUID
,
1646 .write_clear_fn
= ldif_write_objectGUID
,
1647 .write_hex_fn
= extended_dn_write_hex
1649 .name
= "RMD_FLAGS",
1650 .read_fn
= ldb_handler_copy
,
1651 .write_clear_fn
= ldb_handler_copy
,
1652 .write_hex_fn
= ldb_handler_copy
1654 .name
= "RMD_ADDTIME",
1655 .read_fn
= ldb_handler_copy
,
1656 .write_clear_fn
= ldb_handler_copy
,
1657 .write_hex_fn
= ldb_handler_copy
1659 .name
= "RMD_CHANGETIME",
1660 .read_fn
= ldb_handler_copy
,
1661 .write_clear_fn
= ldb_handler_copy
,
1662 .write_hex_fn
= ldb_handler_copy
1664 .name
= "RMD_LOCAL_USN",
1665 .read_fn
= ldb_handler_copy
,
1666 .write_clear_fn
= ldb_handler_copy
,
1667 .write_hex_fn
= ldb_handler_copy
1669 .name
= "RMD_ORIGINATING_USN",
1670 .read_fn
= ldb_handler_copy
,
1671 .write_clear_fn
= ldb_handler_copy
,
1672 .write_hex_fn
= ldb_handler_copy
1674 .name
= "RMD_VERSION",
1675 .read_fn
= ldb_handler_copy
,
1676 .write_clear_fn
= ldb_handler_copy
,
1677 .write_hex_fn
= ldb_handler_copy
1681 /* TODO: Should be dynamic at some point */
1682 static const struct {
1685 } samba_attributes
[] = {
1686 { "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR
},
1687 { "oMSyntax", LDB_SYNTAX_SAMBA_INT32
},
1688 { "objectCategory", LDB_SYNTAX_SAMBA_OBJECT_CATEGORY
},
1689 { "schemaInfo", LDB_SYNTAX_SAMBA_SCHEMAINFO
},
1690 { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP
},
1691 { "repsFrom", LDB_SYNTAX_SAMBA_REPSFROMTO
},
1692 { "repsTo", LDB_SYNTAX_SAMBA_REPSFROMTO
},
1693 { "replPropertyMetaData", LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA
},
1694 { "replUpToDateVector", LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR
},
1695 { "msDS-RevealedUsers", LDB_SYNTAX_SAMBA_REVEALEDUSERS
},
1696 { "trustAuthIncoming", LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
},
1697 { "trustAuthOutgoing", LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB
},
1698 { "msDS-TrustForestTrustInfo", LDB_SYNTAX_SAMBA_FORESTTRUSTINFO
},
1699 { "rIDAllocationPool", LDB_SYNTAX_SAMBA_RANGE64
},
1700 { "rIDPreviousAllocationPool", LDB_SYNTAX_SAMBA_RANGE64
},
1701 { "rIDAvailablePool", LDB_SYNTAX_SAMBA_RANGE64
},
1702 { "defaultSecurityDescriptor", LDB_SYNTAX_SAMBA_SDDL_SECURITY_DESCRIPTOR
},
1705 * these are extracted by searching
1706 * (&(attributeSyntax=2.5.5.17)(omSyntax=4))
1708 * Except: msAuthz-CentralAccessPolicyID as it might be a GUID see:
1709 * adminDescription: For a Central Access Policy, this attribute defines a GUID t
1710 * hat can be used to identify the set of policies when applied to a resource.
1711 * Until we see a msAuthz-CentralAccessPolicyID value on a windows
1712 * server, we ignore it here.
1714 { "mS-DS-CreatorSID", LDB_SYNTAX_SAMBA_SID
},
1715 { "msDS-QuotaTrustee", LDB_SYNTAX_SAMBA_SID
},
1716 { "objectSid", LDB_SYNTAX_SAMBA_SID
},
1717 { "tokenGroups", LDB_SYNTAX_SAMBA_SID
},
1718 { "tokenGroupsGlobalAndUniversal", LDB_SYNTAX_SAMBA_SID
},
1719 { "tokenGroupsNoGCAcceptable", LDB_SYNTAX_SAMBA_SID
},
1720 { "securityIdentifier", LDB_SYNTAX_SAMBA_SID
},
1721 { "sIDHistory", LDB_SYNTAX_SAMBA_SID
},
1722 { "syncWithSID", LDB_SYNTAX_SAMBA_SID
},
1725 * these are extracted by searching
1726 * (&(attributeSyntax=2.5.5.10)(rangeLower=16)(rangeUpper=16)(omSyntax=4))
1728 { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID
},
1729 { "categoryId", LDB_SYNTAX_SAMBA_GUID
},
1730 { "controlAccessRights", LDB_SYNTAX_SAMBA_GUID
},
1731 { "currMachineId", LDB_SYNTAX_SAMBA_GUID
},
1732 { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID
},
1733 { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID
},
1734 { "implementedCategories", LDB_SYNTAX_SAMBA_GUID
},
1735 { "msDS-AzObjectGuid", LDB_SYNTAX_SAMBA_GUID
},
1736 { "msDS-GenerationId", LDB_SYNTAX_SAMBA_GUID
},
1737 { "msDS-OptionalFeatureGUID", LDB_SYNTAX_SAMBA_GUID
},
1738 { "msDFSR-ContentSetGuid", LDB_SYNTAX_SAMBA_GUID
},
1739 { "msDFSR-ReplicationGroupGuid", LDB_SYNTAX_SAMBA_GUID
},
1740 { "mSMQDigests", LDB_SYNTAX_SAMBA_GUID
},
1741 { "mSMQOwnerID", LDB_SYNTAX_SAMBA_GUID
},
1742 { "mSMQQMID", LDB_SYNTAX_SAMBA_GUID
},
1743 { "mSMQQueueType", LDB_SYNTAX_SAMBA_GUID
},
1744 { "mSMQSites", LDB_SYNTAX_SAMBA_GUID
},
1745 { "netbootGUID", LDB_SYNTAX_SAMBA_GUID
},
1746 { "objectGUID", LDB_SYNTAX_SAMBA_GUID
},
1747 { "pKTGuid", LDB_SYNTAX_SAMBA_GUID
},
1748 { "requiredCategories", LDB_SYNTAX_SAMBA_GUID
},
1749 { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID
},
1750 { "siteGUID", LDB_SYNTAX_SAMBA_GUID
},
1751 { "msDFS-GenerationGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1752 { "msDFS-LinkIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1753 { "msDFS-NamespaceIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID
},
1754 { "msSPP-CSVLKSkuId", LDB_SYNTAX_SAMBA_GUID
},
1755 { "msSPP-KMSIds", LDB_SYNTAX_SAMBA_GUID
},
1758 * these are known to be GUIDs
1760 { "invocationId", LDB_SYNTAX_SAMBA_GUID
},
1761 { "parentGUID", LDB_SYNTAX_SAMBA_GUID
},
1763 /* These NDR encoded things we want to be able to read with --show-binary */
1764 { "dnsRecord", LDB_SYNTAX_SAMBA_DNSRECORD
},
1765 { "dNSProperty", LDB_SYNTAX_SAMBA_DNSPROPERTY
},
1766 { "supplementalCredentials", LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS
},
1767 { "partialAttributeSet", LDB_SYNTAX_SAMBA_PARTIALATTRIBUTESET
}
1770 const struct ldb_schema_syntax
*ldb_samba_syntax_by_name(struct ldb_context
*ldb
, const char *name
)
1773 const struct ldb_schema_syntax
*s
= NULL
;
1775 for (j
=0; j
< ARRAY_SIZE(samba_syntaxes
); j
++) {
1776 if (strcmp(name
, samba_syntaxes
[j
].name
) == 0) {
1777 s
= &samba_syntaxes
[j
];
1784 const struct ldb_schema_syntax
*ldb_samba_syntax_by_lDAPDisplayName(struct ldb_context
*ldb
, const char *name
)
1787 const struct ldb_schema_syntax
*s
= NULL
;
1789 for (j
=0; j
< ARRAY_SIZE(samba_attributes
); j
++) {
1790 if (strcmp(samba_attributes
[j
].name
, name
) == 0) {
1791 s
= ldb_samba_syntax_by_name(ldb
, samba_attributes
[j
].syntax
);
1799 static const char *secret_attributes
[] = {DSDB_SECRET_ATTRIBUTES
, "secret",
1800 "priorSecret", NULL
};
1803 register the samba ldif handlers
1805 int ldb_register_samba_handlers(struct ldb_context
*ldb
)
1810 if (ldb_get_opaque(ldb
, "SAMBA_HANDLERS_REGISTERED") != NULL
) {
1814 ret
= ldb_set_opaque(ldb
, LDB_SECRET_ATTRIBUTE_LIST_OPAQUE
, discard_const_p(char *, secret_attributes
));
1815 if (ret
!= LDB_SUCCESS
) {
1819 for (i
=0; i
< ARRAY_SIZE(samba_attributes
); i
++) {
1820 const struct ldb_schema_syntax
*s
= NULL
;
1822 s
= ldb_samba_syntax_by_name(ldb
, samba_attributes
[i
].syntax
);
1825 s
= ldb_standard_syntax_by_name(ldb
, samba_attributes
[i
].syntax
);
1829 return LDB_ERR_OPERATIONS_ERROR
;
1832 ret
= ldb_schema_attribute_add_with_syntax(ldb
, samba_attributes
[i
].name
, LDB_ATTR_FLAG_FIXED
, s
);
1833 if (ret
!= LDB_SUCCESS
) {
1838 for (i
=0; i
< ARRAY_SIZE(samba_dn_syntax
); i
++) {
1839 ret
= ldb_dn_extended_add_syntax(ldb
, LDB_ATTR_FLAG_FIXED
, &samba_dn_syntax
[i
]);
1840 if (ret
!= LDB_SUCCESS
) {
1846 ret
= ldb_register_samba_matching_rules(ldb
);
1847 if (ret
!= LDB_SUCCESS
) {
1852 ret
= ldb_set_opaque(ldb
, "SAMBA_HANDLERS_REGISTERED", (void*)1);
1853 if (ret
!= LDB_SUCCESS
) {