s4-dsdb: use ldb_val_to_time() instead of ldb_string_to_time()
[Samba/fernandojvsilva.git] / source4 / dsdb / samdb / ldb_modules / simple_ldap_map.c
blobbf9cd4fdda4a7d42e13e55d5c41758d32d00a7e2
1 /*
2 ldb database module
4 LDAP semantics mapping module
6 Copyright (C) Jelmer Vernooij 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /*
24 This module relies on ldb_map to do all the real work, but performs
25 some of the trivial mappings between AD semantics and that provided
26 by OpenLDAP and similar servers.
29 #include "includes.h"
30 #include "ldb/include/ldb_module.h"
31 #include "ldb/ldb_map/ldb_map.h"
33 #include "librpc/gen_ndr/ndr_misc.h"
34 #include "librpc/ndr/libndr.h"
35 #include "dsdb/samdb/samdb.h"
36 #include "../../../lib/ldb/include/ldb_handlers.h"
38 struct entryuuid_private {
39 struct ldb_context *ldb;
40 struct ldb_dn **base_dns;
43 static struct ldb_val encode_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
45 struct GUID guid;
46 NTSTATUS status = GUID_from_data_blob(val, &guid);
47 struct ldb_val out = data_blob(NULL, 0);
49 if (!NT_STATUS_IS_OK(status)) {
50 return out;
52 status = GUID_to_ndr_blob(&guid, ctx, &out);
53 if (!NT_STATUS_IS_OK(status)) {
54 return data_blob(NULL, 0);
57 return out;
60 static struct ldb_val guid_always_string(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
62 struct ldb_val out = data_blob(NULL, 0);
63 struct GUID guid;
64 NTSTATUS status = GUID_from_data_blob(val, &guid);
65 if (!NT_STATUS_IS_OK(status)) {
66 return out;
68 return data_blob_string_const(GUID_string(ctx, &guid));
71 static struct ldb_val encode_ns_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
73 struct GUID guid;
74 NTSTATUS status = NS_GUID_from_string((char *)val->data, &guid);
75 struct ldb_val out = data_blob(NULL, 0);
77 if (!NT_STATUS_IS_OK(status)) {
78 return out;
80 status = GUID_to_ndr_blob(&guid, ctx, &out);
81 if (!NT_STATUS_IS_OK(status)) {
82 return data_blob(NULL, 0);
85 return out;
88 static struct ldb_val guid_ns_string(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
90 struct ldb_val out = data_blob(NULL, 0);
91 struct GUID guid;
92 NTSTATUS status = GUID_from_data_blob(val, &guid);
93 if (!NT_STATUS_IS_OK(status)) {
94 return out;
96 return data_blob_string_const(NS_GUID_string(ctx, &guid));
99 /* The backend holds binary sids, so just copy them back */
100 static struct ldb_val val_copy(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
102 struct ldb_val out = data_blob(NULL, 0);
103 out = ldb_val_dup(ctx, val);
105 return out;
108 /* Ensure we always convert sids into binary, so the backend doesn't have to know about both forms */
109 static struct ldb_val sid_always_binary(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
111 struct ldb_context *ldb = ldb_module_get_ctx(module);
112 struct ldb_val out = data_blob(NULL, 0);
113 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, "objectSid");
115 if (a->syntax->canonicalise_fn(ldb, ctx, val, &out) != LDB_SUCCESS) {
116 return data_blob(NULL, 0);
119 return out;
122 /* Ensure we always convert sids into string, so the backend doesn't have to know about both forms */
123 static struct ldb_val sid_always_string(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
125 struct ldb_context *ldb = ldb_module_get_ctx(module);
126 struct ldb_val out = data_blob(NULL, 0);
128 if (ldif_comparision_objectSid_isString(val)) {
129 if (ldb_handler_copy(ldb, ctx, val, &out) != LDB_SUCCESS) {
130 return data_blob(NULL, 0);
133 } else {
134 if (ldif_write_objectSid(ldb, ctx, val, &out) != LDB_SUCCESS) {
135 return data_blob(NULL, 0);
138 return out;
141 /* Ensure we always convert objectCategory into a DN */
142 static struct ldb_val objectCategory_always_dn(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
144 struct ldb_context *ldb = ldb_module_get_ctx(module);
145 struct ldb_dn *dn;
146 struct ldb_val out = data_blob(NULL, 0);
147 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, "objectCategory");
149 dn = ldb_dn_from_ldb_val(ctx, ldb, val);
150 if (dn && ldb_dn_validate(dn)) {
151 talloc_free(dn);
152 return val_copy(module, ctx, val);
154 talloc_free(dn);
156 if (a->syntax->canonicalise_fn(ldb, ctx, val, &out) != LDB_SUCCESS) {
157 return data_blob(NULL, 0);
160 return out;
163 static struct ldb_val normalise_to_signed32(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
165 struct ldb_val out;
166 /* We've to use "strtoll" here to have the intended overflows.
167 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
168 int32_t i = (int32_t) strtoll((char *)val->data, NULL, 0);
169 out = data_blob_string_const(talloc_asprintf(ctx, "%d", i));
170 return out;
173 static struct ldb_val usn_to_entryCSN(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
175 struct ldb_val out;
176 unsigned long long usn = strtoull((const char *)val->data, NULL, 10);
177 time_t t = (usn >> 24);
178 out = data_blob_string_const(talloc_asprintf(ctx, "%s#%06x#00#000000", ldb_timestring(ctx, t), (unsigned int)(usn & 0xFFFFFF)));
179 return out;
182 static unsigned long long entryCSN_to_usn_int(TALLOC_CTX *ctx, const struct ldb_val *val)
184 char *entryCSN = talloc_strndup(ctx, (const char *)val->data, val->length);
185 char *mod_per_sec;
186 time_t t;
187 unsigned long long usn;
188 char *p;
189 if (!entryCSN) {
190 return 0;
192 p = strchr(entryCSN, '#');
193 if (!p) {
194 return 0;
196 p[0] = '\0';
197 p++;
198 mod_per_sec = p;
200 p = strchr(p, '#');
201 if (!p) {
202 return 0;
204 p[0] = '\0';
205 p++;
207 usn = strtol(mod_per_sec, NULL, 16);
209 t = ldb_string_to_time(entryCSN);
211 usn = usn | ((unsigned long long)t <<24);
212 return usn;
215 static struct ldb_val entryCSN_to_usn(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
217 struct ldb_val out;
218 unsigned long long usn = entryCSN_to_usn_int(ctx, val);
219 out = data_blob_string_const(talloc_asprintf(ctx, "%lld", usn));
220 return out;
223 static struct ldb_val usn_to_timestamp(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
225 struct ldb_val out;
226 unsigned long long usn = strtoull((const char *)val->data, NULL, 10);
227 time_t t = (usn >> 24);
228 out = data_blob_string_const(ldb_timestring(ctx, t));
229 return out;
232 static struct ldb_val timestamp_to_usn(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
234 struct ldb_val out;
235 time_t t=0;
236 unsigned long long usn;
238 ldb_val_to_time(val, &t);
240 usn = ((unsigned long long)t <<24);
242 out = data_blob_string_const(talloc_asprintf(ctx, "%lld", usn));
243 return out;
247 static const struct ldb_map_attribute entryuuid_attributes[] =
249 /* objectGUID */
251 .local_name = "objectGUID",
252 .type = LDB_MAP_CONVERT,
253 .u = {
254 .convert = {
255 .remote_name = "entryUUID",
256 .convert_local = guid_always_string,
257 .convert_remote = encode_guid,
261 /* invocationId */
263 .local_name = "invocationId",
264 .type = LDB_MAP_CONVERT,
265 .u = {
266 .convert = {
267 .remote_name = "invocationId",
268 .convert_local = guid_always_string,
269 .convert_remote = encode_guid,
273 /* objectSid */
275 .local_name = "objectSid",
276 .type = LDB_MAP_CONVERT,
277 .u = {
278 .convert = {
279 .remote_name = "objectSid",
280 .convert_local = sid_always_binary,
281 .convert_remote = val_copy,
286 .local_name = "name",
287 .type = LDB_MAP_RENAME,
288 .u = {
289 .rename = {
290 .remote_name = "samba4RDN"
295 .local_name = "whenCreated",
296 .type = LDB_MAP_RENAME,
297 .u = {
298 .rename = {
299 .remote_name = "createTimestamp"
304 .local_name = "whenChanged",
305 .type = LDB_MAP_RENAME,
306 .u = {
307 .rename = {
308 .remote_name = "modifyTimestamp"
313 .local_name = "objectClasses",
314 .type = LDB_MAP_RENAME,
315 .u = {
316 .rename = {
317 .remote_name = "samba4ObjectClasses"
322 .local_name = "dITContentRules",
323 .type = LDB_MAP_RENAME,
324 .u = {
325 .rename = {
326 .remote_name = "samba4DITContentRules"
331 .local_name = "attributeTypes",
332 .type = LDB_MAP_RENAME,
333 .u = {
334 .rename = {
335 .remote_name = "samba4AttributeTypes"
340 .local_name = "objectCategory",
341 .type = LDB_MAP_CONVERT,
342 .u = {
343 .convert = {
344 .remote_name = "objectCategory",
345 .convert_local = objectCategory_always_dn,
346 .convert_remote = val_copy,
351 .local_name = "distinguishedName",
352 .type = LDB_MAP_RENAME,
353 .u = {
354 .rename = {
355 .remote_name = "entryDN"
360 .local_name = "primaryGroupID",
361 .type = LDB_MAP_CONVERT,
362 .u = {
363 .convert = {
364 .remote_name = "primaryGroupID",
365 .convert_local = normalise_to_signed32,
366 .convert_remote = val_copy,
371 .local_name = "groupType",
372 .type = LDB_MAP_CONVERT,
373 .u = {
374 .convert = {
375 .remote_name = "groupType",
376 .convert_local = normalise_to_signed32,
377 .convert_remote = val_copy,
382 .local_name = "userAccountControl",
383 .type = LDB_MAP_CONVERT,
384 .u = {
385 .convert = {
386 .remote_name = "userAccountControl",
387 .convert_local = normalise_to_signed32,
388 .convert_remote = val_copy,
393 .local_name = "sAMAccountType",
394 .type = LDB_MAP_CONVERT,
395 .u = {
396 .convert = {
397 .remote_name = "sAMAccountType",
398 .convert_local = normalise_to_signed32,
399 .convert_remote = val_copy,
404 .local_name = "systemFlags",
405 .type = LDB_MAP_CONVERT,
406 .u = {
407 .convert = {
408 .remote_name = "systemFlags",
409 .convert_local = normalise_to_signed32,
410 .convert_remote = val_copy,
415 .local_name = "usnChanged",
416 .type = LDB_MAP_CONVERT,
417 .u = {
418 .convert = {
419 .remote_name = "entryCSN",
420 .convert_local = usn_to_entryCSN,
421 .convert_remote = entryCSN_to_usn
426 .local_name = "usnCreated",
427 .type = LDB_MAP_CONVERT,
428 .u = {
429 .convert = {
430 .remote_name = "createTimestamp",
431 .convert_local = usn_to_timestamp,
432 .convert_remote = timestamp_to_usn,
437 .local_name = "*",
438 .type = LDB_MAP_KEEP,
441 .local_name = NULL,
445 /* This objectClass conflicts with builtin classes on OpenLDAP */
446 const struct ldb_map_objectclass entryuuid_objectclasses[] =
449 .local_name = "subSchema",
450 .remote_name = "samba4SubSchema"
453 .local_name = NULL
457 /* These things do not show up in wildcard searches in OpenLDAP, but
458 * we need them to show up in the AD-like view */
459 static const char * const entryuuid_wildcard_attributes[] = {
460 "objectGUID",
461 "whenCreated",
462 "whenChanged",
463 "usnCreated",
464 "usnChanged",
465 "memberOf",
466 NULL
469 static const struct ldb_map_attribute nsuniqueid_attributes[] =
471 /* objectGUID */
473 .local_name = "objectGUID",
474 .type = LDB_MAP_CONVERT,
475 .u = {
476 .convert = {
477 .remote_name = "nsuniqueid",
478 .convert_local = guid_ns_string,
479 .convert_remote = encode_ns_guid,
483 /* objectSid */
485 .local_name = "objectSid",
486 .type = LDB_MAP_CONVERT,
487 .u = {
488 .convert = {
489 .remote_name = "sambaSID",
490 .convert_local = sid_always_string,
491 .convert_remote = sid_always_binary,
496 .local_name = "whenCreated",
497 .type = LDB_MAP_RENAME,
498 .u = {
499 .rename = {
500 .remote_name = "createTimestamp"
505 .local_name = "whenChanged",
506 .type = LDB_MAP_RENAME,
507 .u = {
508 .rename = {
509 .remote_name = "modifyTimestamp"
514 .local_name = "objectCategory",
515 .type = LDB_MAP_CONVERT,
516 .u = {
517 .convert = {
518 .remote_name = "objectCategory",
519 .convert_local = objectCategory_always_dn,
520 .convert_remote = val_copy,
525 .local_name = "distinguishedName",
526 .type = LDB_MAP_RENAME,
527 .u = {
528 .rename = {
529 .remote_name = "entryDN"
534 .local_name = "primaryGroupID",
535 .type = LDB_MAP_CONVERT,
536 .u = {
537 .convert = {
538 .remote_name = "primaryGroupID",
539 .convert_local = normalise_to_signed32,
540 .convert_remote = val_copy,
545 .local_name = "groupType",
546 .type = LDB_MAP_CONVERT,
547 .u = {
548 .convert = {
549 .remote_name = "sambaGroupType",
550 .convert_local = normalise_to_signed32,
551 .convert_remote = val_copy,
556 .local_name = "userAccountControl",
557 .type = LDB_MAP_CONVERT,
558 .u = {
559 .convert = {
560 .remote_name = "userAccountControl",
561 .convert_local = normalise_to_signed32,
562 .convert_remote = val_copy,
567 .local_name = "sAMAccountType",
568 .type = LDB_MAP_CONVERT,
569 .u = {
570 .convert = {
571 .remote_name = "sAMAccountType",
572 .convert_local = normalise_to_signed32,
573 .convert_remote = val_copy,
578 .local_name = "systemFlags",
579 .type = LDB_MAP_CONVERT,
580 .u = {
581 .convert = {
582 .remote_name = "systemFlags",
583 .convert_local = normalise_to_signed32,
584 .convert_remote = val_copy,
589 .local_name = "usnChanged",
590 .type = LDB_MAP_CONVERT,
591 .u = {
592 .convert = {
593 .remote_name = "modifyTimestamp",
594 .convert_local = usn_to_timestamp,
595 .convert_remote = timestamp_to_usn,
600 .local_name = "usnCreated",
601 .type = LDB_MAP_CONVERT,
602 .u = {
603 .convert = {
604 .remote_name = "createTimestamp",
605 .convert_local = usn_to_timestamp,
606 .convert_remote = timestamp_to_usn,
611 .local_name = "pwdLastSet",
612 .type = LDB_MAP_RENAME,
613 .u = {
614 .rename = {
615 .remote_name = "sambaPwdLastSet"
620 .local_name = "lastLogon",
621 .type = LDB_MAP_RENAME,
622 .u = {
623 .rename = {
624 .remote_name = "sambaLogonTime"
629 .local_name = "lastLogoff",
630 .type = LDB_MAP_RENAME,
631 .u = {
632 .rename = {
633 .remote_name = "sambaLogoffTime"
638 .local_name = "badPwdCount",
639 .type = LDB_MAP_RENAME,
640 .u = {
641 .rename = {
642 .remote_name = "sambaBadPasswordCount"
647 .local_name = "logonHours",
648 .type = LDB_MAP_RENAME,
649 .u = {
650 .rename = {
651 .remote_name = "sambaLogonHours"
656 .local_name = "homeDrive",
657 .type = LDB_MAP_RENAME,
658 .u = {
659 .rename = {
660 .remote_name = "sambaHomeDrive"
665 .local_name = "scriptPath",
666 .type = LDB_MAP_RENAME,
667 .u = {
668 .rename = {
669 .remote_name = "sambaLogonScript"
674 .local_name = "profilePath",
675 .type = LDB_MAP_RENAME,
676 .u = {
677 .rename = {
678 .remote_name = "sambaProfilePath"
683 .local_name = "userWorkstations",
684 .type = LDB_MAP_RENAME,
685 .u = {
686 .rename = {
687 .remote_name = "sambaUserWorkstations"
692 .local_name = "homeDirectory",
693 .type = LDB_MAP_RENAME,
694 .u = {
695 .rename = {
696 .remote_name = "sambaHomePath"
701 .local_name = "nextRid",
702 .type = LDB_MAP_RENAME,
703 .u = {
704 .rename = {
705 .remote_name = "sambaNextRid"
710 .local_name = "privilegeDisplayName",
711 .type = LDB_MAP_RENAME,
712 .u = {
713 .rename = {
714 .remote_name = "sambaPrivName"
719 .local_name = "*",
720 .type = LDB_MAP_KEEP,
723 .local_name = NULL,
727 /* This objectClass conflicts with builtin classes on FDS */
728 const struct ldb_map_objectclass nsuniqueid_objectclasses[] =
731 .local_name = NULL
735 /* These things do not show up in wildcard searches in OpenLDAP, but
736 * we need them to show up in the AD-like view */
737 static const char * const nsuniqueid_wildcard_attributes[] = {
738 "objectGUID",
739 "whenCreated",
740 "whenChanged",
741 "usnCreated",
742 "usnChanged",
743 NULL
746 /* the context init function */
747 static int entryuuid_init(struct ldb_module *module)
749 int ret;
750 ret = ldb_map_init(module, entryuuid_attributes, entryuuid_objectclasses, entryuuid_wildcard_attributes, "samba4Top", NULL);
751 if (ret != LDB_SUCCESS)
752 return ret;
754 return ldb_next_init(module);
757 /* the context init function */
758 static int nsuniqueid_init(struct ldb_module *module)
760 int ret;
761 ret = ldb_map_init(module, nsuniqueid_attributes, nsuniqueid_objectclasses, nsuniqueid_wildcard_attributes, "extensibleObject", NULL);
762 if (ret != LDB_SUCCESS)
763 return ret;
765 return ldb_next_init(module);
768 static int get_seq_callback(struct ldb_request *req,
769 struct ldb_reply *ares)
771 unsigned long long *seq = (unsigned long long *)req->context;
773 if (!ares) {
774 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
776 if (ares->error != LDB_SUCCESS) {
777 return ldb_request_done(req, ares->error);
780 if (ares->type == LDB_REPLY_ENTRY) {
781 struct ldb_message_element *el = ldb_msg_find_element(ares->message, "contextCSN");
782 if (el) {
783 *seq = entryCSN_to_usn_int(ares, &el->values[0]);
787 if (ares->type == LDB_REPLY_DONE) {
788 return ldb_request_done(req, LDB_SUCCESS);
791 talloc_free(ares);
792 return LDB_SUCCESS;
795 static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_request *req)
797 struct ldb_context *ldb;
798 int ret;
799 struct map_private *map_private;
800 struct entryuuid_private *entryuuid_private;
801 unsigned long long seq_num = 0;
802 struct ldb_request *search_req;
804 const struct ldb_control *partition_ctrl;
805 const struct dsdb_control_current_partition *partition;
807 static const char *contextCSN_attr[] = {
808 "contextCSN", NULL
811 struct ldb_seqnum_request *seq;
812 struct ldb_seqnum_result *seqr;
813 struct ldb_extended *ext;
815 ldb = ldb_module_get_ctx(module);
817 seq = talloc_get_type(req->op.extended.data, struct ldb_seqnum_request);
819 map_private = talloc_get_type(ldb_module_get_private(module), struct map_private);
821 entryuuid_private = talloc_get_type(map_private->caller_private, struct entryuuid_private);
823 /* All this to get the DN of the parition, so we can search the right thing */
824 partition_ctrl = ldb_request_get_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID);
825 if (!partition_ctrl) {
826 ldb_debug_set(ldb, LDB_DEBUG_FATAL,
827 "entryuuid_sequence_number: no current partition control found");
828 return LDB_ERR_CONSTRAINT_VIOLATION;
831 partition = talloc_get_type(partition_ctrl->data,
832 struct dsdb_control_current_partition);
833 SMB_ASSERT(partition && partition->version == DSDB_CONTROL_CURRENT_PARTITION_VERSION);
835 ret = ldb_build_search_req(&search_req, ldb, req,
836 partition->dn, LDB_SCOPE_BASE,
837 NULL, contextCSN_attr, NULL,
838 &seq_num, get_seq_callback,
839 NULL);
840 if (ret != LDB_SUCCESS) {
841 return ret;
844 ret = ldb_next_request(module, search_req);
846 if (ret == LDB_SUCCESS) {
847 ret = ldb_wait(search_req->handle, LDB_WAIT_ALL);
850 talloc_free(search_req);
851 if (ret != LDB_SUCCESS) {
852 return ret;
855 ext = talloc_zero(req, struct ldb_extended);
856 if (!ext) {
857 return LDB_ERR_OPERATIONS_ERROR;
859 seqr = talloc_zero(req, struct ldb_seqnum_result);
860 if (seqr == NULL) {
861 talloc_free(ext);
862 return LDB_ERR_OPERATIONS_ERROR;
864 ext->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
865 ext->data = seqr;
867 switch (seq->type) {
868 case LDB_SEQ_HIGHEST_SEQ:
869 seqr->seq_num = seq_num;
870 break;
871 case LDB_SEQ_NEXT:
872 seqr->seq_num = seq_num;
873 seqr->seq_num++;
874 break;
875 case LDB_SEQ_HIGHEST_TIMESTAMP:
877 seqr->seq_num = (seq_num >> 24);
878 break;
881 seqr->flags = 0;
882 seqr->flags |= LDB_SEQ_TIMESTAMP_SEQUENCE;
883 seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE;
885 /* send request done */
886 return ldb_module_done(req, NULL, ext, LDB_SUCCESS);
889 static int entryuuid_extended(struct ldb_module *module, struct ldb_request *req)
891 if (strcmp(req->op.extended.oid, LDB_EXTENDED_SEQUENCE_NUMBER) == 0) {
892 return entryuuid_sequence_number(module, req);
895 return ldb_next_request(module, req);
898 _PUBLIC_ const struct ldb_module_ops ldb_entryuuid_module_ops = {
899 .name = "entryuuid",
900 .init_context = entryuuid_init,
901 .extended = entryuuid_extended,
902 LDB_MAP_OPS
905 _PUBLIC_ const struct ldb_module_ops ldb_nsuniqueid_module_ops = {
906 .name = "nsuniqueid",
907 .init_context = nsuniqueid_init,
908 .extended = entryuuid_extended,
909 LDB_MAP_OPS