2 ldb database mapping module
4 Copyright (C) Jelmer Vernooij 2005
5 Copyright (C) Martin Kuehl <mkhl@samba.org> 2006
6 Copyright (C) Simo Sorce <idra@samba.org> 2008
8 ** NOTE! The following LGPL license applies to the ldb
9 ** library. This does NOT imply that all of Samba is released
12 This library is free software; you can redistribute it and/or
13 modify it under the terms of the GNU Lesser General Public
14 License as published by the Free Software Foundation; either
15 version 3 of the License, or (at your option) any later version.
17 This library is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 Lesser General Public License for more details.
22 You should have received a copy of the GNU Lesser General Public
23 License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "system/filesys.h"
29 #include "system/time.h"
31 #include "ldb_map_private.h"
34 /* Mapping message elements
35 * ======================== */
37 /* Map a message element into the remote partition. */
38 static struct ldb_message_element
*ldb_msg_el_map_local(struct ldb_module
*module
, void *mem_ctx
, const struct ldb_map_attribute
*map
, const struct ldb_message_element
*old
)
40 struct ldb_message_element
*el
;
43 el
= talloc_zero(mem_ctx
, struct ldb_message_element
);
49 el
->num_values
= old
->num_values
;
50 el
->values
= talloc_array(el
, struct ldb_val
, el
->num_values
);
51 if (el
->values
== NULL
) {
57 el
->name
= map_attr_map_local(el
, map
, old
->name
);
59 for (i
= 0; i
< el
->num_values
; i
++) {
60 el
->values
[i
] = ldb_val_map_local(module
, el
->values
, map
, &old
->values
[i
]);
66 /* Add a message element either to a local or to a remote message,
67 * depending on whether it goes into the local or remote partition. */
68 static int ldb_msg_el_partition(struct ldb_module
*module
, enum ldb_request_type optype
, struct ldb_message
*local
, struct ldb_message
*remote
, const struct ldb_message
*msg
, const char *attr_name
, /* const char * const names[], */ const struct ldb_message_element
*old
)
70 const struct ldb_map_context
*data
= map_get_context(module
);
71 const struct ldb_map_attribute
*map
= map_attr_find_local(data
, attr_name
);
72 struct ldb_message_element
*el
=NULL
;
73 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
75 /* Unknown attribute: ignore */
77 ldb_debug(ldb
, LDB_DEBUG_WARNING
, "ldb_map: "
78 "Not mapping attribute '%s': no mapping found",
85 if (optype
!= LDB_ADD
) {
86 /* do the same as LDB_MAP_RENAME */
87 el
= ldb_msg_el_map_local(module
, remote
, map
, old
);
95 if (map
->u
.convert
.convert_local
== NULL
) {
96 ldb_debug(ldb
, LDB_DEBUG_WARNING
, "ldb_map: "
97 "Not mapping attribute '%s': "
98 "'convert_local' not set",
105 el
= ldb_msg_el_map_local(module
, remote
, map
, old
);
108 case LDB_MAP_GENERATE
:
109 if (map
->u
.generate
.generate_remote
== NULL
) {
110 ldb_debug(ldb
, LDB_DEBUG_WARNING
, "ldb_map: "
111 "Not mapping attribute '%s': "
112 "'generate_remote' not set",
117 /* TODO: if this attr requires context:
118 * make sure all context attrs are mappable (in 'names')
119 * make sure all context attrs have already been mapped?
120 * maybe postpone generation until they have been mapped?
123 map
->u
.generate
.generate_remote(module
, map
->local_name
, msg
, remote
, local
);
131 return ldb_msg_add(remote
, el
, old
->flags
);
134 el
= talloc(local
, struct ldb_message_element
);
140 *el
= *old
; /* copy the old element */
142 return ldb_msg_add(local
, el
, old
->flags
);
146 * ================ */
148 /* Check whether a message will be (partially) mapped into the remote partition. */
149 static bool ldb_msg_check_remote(struct ldb_module
*module
, const struct ldb_message
*msg
)
151 const struct ldb_map_context
*data
= map_get_context(module
);
155 for (i
= 0; i
< msg
->num_elements
; i
++) {
156 ret
= map_attr_check_remote(data
, msg
->elements
[i
].name
);
165 /* Split message elements that stay in the local partition from those
166 * that are mapped into the remote partition. */
167 static int ldb_msg_partition(struct ldb_module
*module
, enum ldb_request_type optype
, struct ldb_message
*local
, struct ldb_message
*remote
, const struct ldb_message
*msg
)
169 /* const char * const names[]; */
170 struct ldb_context
*ldb
;
174 ldb
= ldb_module_get_ctx(module
);
176 for (i
= 0; i
< msg
->num_elements
; i
++) {
177 /* Skip 'IS_MAPPED' */
178 if (ldb_attr_cmp(msg
->elements
[i
].name
, IS_MAPPED
) == 0) {
179 ldb_debug(ldb
, LDB_DEBUG_WARNING
, "ldb_map: "
180 "Skipping attribute '%s'",
181 msg
->elements
[i
].name
);
185 ret
= ldb_msg_el_partition(module
, optype
, local
, remote
, msg
, msg
->elements
[i
].name
, &msg
->elements
[i
]);
195 static int map_add_do_local(struct map_context
*ac
);
196 static int map_modify_do_local(struct map_context
*ac
);
197 static int map_delete_do_local(struct map_context
*ac
);
198 static int map_rename_do_local(struct map_context
*ac
);
199 static int map_rename_do_fixup(struct map_context
*ac
);
200 static int map_rename_local_callback(struct ldb_request
*req
,
201 struct ldb_reply
*ares
);
204 /*****************************************************************************
205 * COMMON INBOUND functions
206 *****************************************************************************/
208 /* Store the DN of a single search result in context. */
209 static int map_search_self_callback(struct ldb_request
*req
, struct ldb_reply
*ares
)
211 struct ldb_context
*ldb
;
212 struct map_context
*ac
;
215 ac
= talloc_get_type(req
->context
, struct map_context
);
216 ldb
= ldb_module_get_ctx(ac
->module
);
219 return ldb_module_done(ac
->req
, NULL
, NULL
,
220 LDB_ERR_OPERATIONS_ERROR
);
222 if (ares
->error
!= LDB_SUCCESS
) {
223 return ldb_module_done(ac
->req
, ares
->controls
,
224 ares
->response
, ares
->error
);
227 /* We are interested only in the single reply */
229 case LDB_REPLY_ENTRY
:
230 /* We have already found a remote DN */
232 ldb_set_errstring(ldb
,
233 "Too many results!");
234 return ldb_module_done(ac
->req
, NULL
, NULL
,
235 LDB_ERR_OPERATIONS_ERROR
);
239 ac
->local_dn
= talloc_steal(ac
, ares
->message
->dn
);
244 switch (ac
->req
->operation
) {
246 ret
= map_modify_do_local(ac
);
249 ret
= map_delete_do_local(ac
);
252 ret
= map_rename_do_local(ac
);
255 /* if we get here we have definitely a problem */
256 ret
= LDB_ERR_OPERATIONS_ERROR
;
258 if (ret
!= LDB_SUCCESS
) {
259 return ldb_module_done(ac
->req
, NULL
, NULL
,
260 LDB_ERR_OPERATIONS_ERROR
);
264 /* ignore referrals */
272 /* Build a request to search the local record by its DN. */
273 static int map_search_self_req(struct ldb_request
**req
,
274 struct map_context
*ac
,
277 /* attrs[] is returned from this function in
278 * ac->search_req->op.search.attrs, so it must be static, as
279 * otherwise the compiler can put it on the stack */
280 static const char * const attrs
[] = { IS_MAPPED
, NULL
};
281 struct ldb_parse_tree
*tree
;
283 /* Limit search to records with 'IS_MAPPED' present */
284 tree
= ldb_parse_tree(ac
, "(" IS_MAPPED
"=*)");
287 return LDB_ERR_OPERATIONS_ERROR
;
290 *req
= map_search_base_req(ac
, dn
, attrs
, tree
,
291 ac
, map_search_self_callback
);
293 return LDB_ERR_OPERATIONS_ERROR
;
299 static int map_op_local_callback(struct ldb_request
*req
,
300 struct ldb_reply
*ares
)
302 struct ldb_context
*ldb
;
303 struct map_context
*ac
;
306 ac
= talloc_get_type(req
->context
, struct map_context
);
307 ldb
= ldb_module_get_ctx(ac
->module
);
310 return ldb_module_done(ac
->req
, NULL
, NULL
,
311 LDB_ERR_OPERATIONS_ERROR
);
313 if (ares
->error
!= LDB_SUCCESS
) {
314 return ldb_module_done(ac
->req
, ares
->controls
,
315 ares
->response
, ares
->error
);
318 if (ares
->type
!= LDB_REPLY_DONE
) {
319 ldb_asprintf_errstring(ldb
, "Invalid LDB reply type %d", ares
->type
);
320 return ldb_module_done(ac
->req
, NULL
, NULL
,
321 LDB_ERR_OPERATIONS_ERROR
);
324 /* Do the remote request. */
325 ret
= ldb_next_remote_request(ac
->module
, ac
->remote_req
);
326 if (ret
!= LDB_SUCCESS
) {
327 return ldb_module_done(ac
->req
, NULL
, NULL
,
328 LDB_ERR_OPERATIONS_ERROR
);
334 static int map_op_remote_callback(struct ldb_request
*req
,
335 struct ldb_reply
*ares
)
337 struct ldb_context
*ldb
;
338 struct map_context
*ac
;
340 ac
= talloc_get_type(req
->context
, struct map_context
);
341 ldb
= ldb_module_get_ctx(ac
->module
);
344 return ldb_module_done(ac
->req
, NULL
, NULL
,
345 LDB_ERR_OPERATIONS_ERROR
);
347 if (ares
->error
!= LDB_SUCCESS
) {
348 return ldb_module_done(ac
->req
, ares
->controls
,
349 ares
->response
, ares
->error
);
352 if (ares
->type
!= LDB_REPLY_DONE
) {
353 ldb_asprintf_errstring(ldb
, "Invalid LDB reply type %d", ares
->type
);
354 return ldb_module_done(ac
->req
, NULL
, NULL
,
355 LDB_ERR_OPERATIONS_ERROR
);
358 return ldb_module_done(ac
->req
, ares
->controls
,
359 ares
->response
, ares
->error
);
363 /*****************************************************************************
365 *****************************************************************************/
369 int ldb_map_add(struct ldb_module
*module
, struct ldb_request
*req
)
371 const struct ldb_message
*msg
= req
->op
.add
.message
;
372 struct ldb_context
*ldb
;
373 struct map_context
*ac
;
374 struct ldb_message
*remote_msg
;
377 ldb
= ldb_module_get_ctx(module
);
379 /* Do not manipulate our control entries */
380 if (ldb_dn_is_special(msg
->dn
)) {
381 return ldb_next_request(module
, req
);
384 /* No mapping requested (perhaps no DN mapping specified), skip to next module */
385 if (!ldb_dn_check_local(module
, msg
->dn
)) {
386 return ldb_next_request(module
, req
);
389 /* No mapping needed, fail */
390 if (!ldb_msg_check_remote(module
, msg
)) {
391 return LDB_ERR_OPERATIONS_ERROR
;
394 /* Prepare context and handle */
395 ac
= map_init_context(module
, req
);
397 return LDB_ERR_OPERATIONS_ERROR
;
401 /* Prepare the local message */
402 ac
->local_msg
= ldb_msg_new(ac
);
403 if (ac
->local_msg
== NULL
) {
405 return LDB_ERR_OPERATIONS_ERROR
;
407 ac
->local_msg
->dn
= msg
->dn
;
409 /* Prepare the remote message */
410 remote_msg
= ldb_msg_new(ac
);
411 if (remote_msg
== NULL
) {
413 return LDB_ERR_OPERATIONS_ERROR
;
415 remote_msg
->dn
= ldb_dn_map_local(ac
->module
, remote_msg
, msg
->dn
);
417 /* Split local from remote message */
418 ldb_msg_partition(module
, req
->operation
, ac
->local_msg
, remote_msg
, msg
);
420 /* Prepare the remote operation */
421 ret
= ldb_build_add_req(&ac
->remote_req
, ldb
,
424 ac
, map_op_remote_callback
,
426 LDB_REQ_SET_LOCATION(ac
->remote_req
);
427 if (ret
!= LDB_SUCCESS
) {
428 return LDB_ERR_OPERATIONS_ERROR
;
431 if ((ac
->local_msg
->num_elements
== 0) ||
432 ( ! map_check_local_db(ac
->module
))) {
433 /* No local data or db, just run the remote request */
434 return ldb_next_remote_request(ac
->module
, ac
->remote_req
);
437 /* Store remote DN in 'IS_MAPPED' */
438 /* TODO: use GUIDs here instead */
439 ret
= ldb_msg_add_linearized_dn(ac
->local_msg
, IS_MAPPED
,
441 if (ret
!= LDB_SUCCESS
) {
442 return LDB_ERR_OPERATIONS_ERROR
;
445 return map_add_do_local(ac
);
448 /* Add the local record. */
449 static int map_add_do_local(struct map_context
*ac
)
451 struct ldb_request
*local_req
;
452 struct ldb_context
*ldb
;
455 ldb
= ldb_module_get_ctx(ac
->module
);
457 /* Prepare the local operation */
458 ret
= ldb_build_add_req(&local_req
, ldb
, ac
,
462 map_op_local_callback
,
464 LDB_REQ_SET_LOCATION(local_req
);
465 if (ret
!= LDB_SUCCESS
) {
466 return LDB_ERR_OPERATIONS_ERROR
;
468 return ldb_next_request(ac
->module
, local_req
);
471 /*****************************************************************************
473 *****************************************************************************/
475 /* Modify a record. */
476 int ldb_map_modify(struct ldb_module
*module
, struct ldb_request
*req
)
478 const struct ldb_message
*msg
= req
->op
.mod
.message
;
479 struct ldb_request
*search_req
;
480 struct ldb_message
*remote_msg
;
481 struct ldb_context
*ldb
;
482 struct map_context
*ac
;
485 ldb
= ldb_module_get_ctx(module
);
487 /* Do not manipulate our control entries */
488 if (ldb_dn_is_special(msg
->dn
)) {
489 return ldb_next_request(module
, req
);
492 /* No mapping requested (perhaps no DN mapping specified), skip to next module */
493 if (!ldb_dn_check_local(module
, msg
->dn
)) {
494 return ldb_next_request(module
, req
);
497 /* No mapping needed, skip to next module */
498 /* TODO: What if the remote part exists, the local doesn't,
499 * and this request wants to modify local data and thus
500 * add the local record? */
501 if (!ldb_msg_check_remote(module
, msg
)) {
502 return LDB_ERR_OPERATIONS_ERROR
;
505 /* Prepare context and handle */
506 ac
= map_init_context(module
, req
);
508 return LDB_ERR_OPERATIONS_ERROR
;
511 /* Prepare the local message */
512 ac
->local_msg
= ldb_msg_new(ac
);
513 if (ac
->local_msg
== NULL
) {
515 return LDB_ERR_OPERATIONS_ERROR
;
517 ac
->local_msg
->dn
= msg
->dn
;
519 /* Prepare the remote message */
520 remote_msg
= ldb_msg_new(ac
->remote_req
);
521 if (remote_msg
== NULL
) {
523 return LDB_ERR_OPERATIONS_ERROR
;
525 remote_msg
->dn
= ldb_dn_map_local(ac
->module
, remote_msg
, msg
->dn
);
527 /* Split local from remote message */
528 ldb_msg_partition(module
, req
->operation
, ac
->local_msg
, remote_msg
, msg
);
530 /* Prepare the remote operation */
531 ret
= ldb_build_mod_req(&ac
->remote_req
, ldb
,
534 ac
, map_op_remote_callback
,
536 LDB_REQ_SET_LOCATION(ac
->remote_req
);
537 if (ret
!= LDB_SUCCESS
) {
538 return LDB_ERR_OPERATIONS_ERROR
;
541 if ((ac
->local_msg
->num_elements
== 0) ||
542 ( ! map_check_local_db(ac
->module
))) {
543 /* No local data or db, just run the remote request */
544 return ldb_next_remote_request(ac
->module
, ac
->remote_req
);
547 /* prepare the search operation */
548 ret
= map_search_self_req(&search_req
, ac
, msg
->dn
);
549 if (ret
!= LDB_SUCCESS
) {
550 return LDB_ERR_OPERATIONS_ERROR
;
553 return ldb_next_request(module
, search_req
);
556 /* Modify the local record. */
557 static int map_modify_do_local(struct map_context
*ac
)
559 struct ldb_request
*local_req
;
560 struct ldb_context
*ldb
;
563 ldb
= ldb_module_get_ctx(ac
->module
);
565 if (ac
->local_dn
== NULL
) {
566 /* No local record present, add it instead */
567 /* Add local 'IS_MAPPED' */
568 /* TODO: use GUIDs here instead */
569 if (ldb_msg_add_empty(ac
->local_msg
, IS_MAPPED
,
570 LDB_FLAG_MOD_ADD
, NULL
) != 0) {
571 return LDB_ERR_OPERATIONS_ERROR
;
573 ret
= ldb_msg_add_linearized_dn(ac
->local_msg
, IS_MAPPED
,
574 ac
->remote_req
->op
.mod
.message
->dn
);
576 return LDB_ERR_OPERATIONS_ERROR
;
579 /* Prepare the local operation */
580 ret
= ldb_build_add_req(&local_req
, ldb
, ac
,
584 map_op_local_callback
,
586 LDB_REQ_SET_LOCATION(local_req
);
587 if (ret
!= LDB_SUCCESS
) {
588 return LDB_ERR_OPERATIONS_ERROR
;
591 /* Prepare the local operation */
592 ret
= ldb_build_mod_req(&local_req
, ldb
, ac
,
596 map_op_local_callback
,
598 LDB_REQ_SET_LOCATION(local_req
);
599 if (ret
!= LDB_SUCCESS
) {
600 return LDB_ERR_OPERATIONS_ERROR
;
604 return ldb_next_request(ac
->module
, local_req
);
607 /*****************************************************************************
609 *****************************************************************************/
611 /* Delete a record. */
612 int ldb_map_delete(struct ldb_module
*module
, struct ldb_request
*req
)
614 struct ldb_request
*search_req
;
615 struct ldb_context
*ldb
;
616 struct map_context
*ac
;
619 ldb
= ldb_module_get_ctx(module
);
621 /* Do not manipulate our control entries */
622 if (ldb_dn_is_special(req
->op
.del
.dn
)) {
623 return ldb_next_request(module
, req
);
626 /* No mapping requested (perhaps no DN mapping specified).
627 * Skip to next module */
628 if (!ldb_dn_check_local(module
, req
->op
.del
.dn
)) {
629 return ldb_next_request(module
, req
);
632 /* Prepare context and handle */
633 ac
= map_init_context(module
, req
);
635 return LDB_ERR_OPERATIONS_ERROR
;
638 /* Prepare the remote operation */
639 ret
= ldb_build_del_req(&ac
->remote_req
, ldb
, ac
,
640 ldb_dn_map_local(module
, ac
, req
->op
.del
.dn
),
643 map_op_remote_callback
,
645 LDB_REQ_SET_LOCATION(ac
->remote_req
);
646 if (ret
!= LDB_SUCCESS
) {
647 return LDB_ERR_OPERATIONS_ERROR
;
650 /* No local db, just run the remote request */
651 if (!map_check_local_db(ac
->module
)) {
652 /* Do the remote request. */
653 return ldb_next_remote_request(ac
->module
, ac
->remote_req
);
656 /* Prepare the search operation */
657 ret
= map_search_self_req(&search_req
, ac
, req
->op
.del
.dn
);
658 if (ret
!= LDB_SUCCESS
) {
660 return LDB_ERR_OPERATIONS_ERROR
;
663 return ldb_next_request(module
, search_req
);
666 /* Delete the local record. */
667 static int map_delete_do_local(struct map_context
*ac
)
669 struct ldb_request
*local_req
;
670 struct ldb_context
*ldb
;
673 ldb
= ldb_module_get_ctx(ac
->module
);
675 /* No local record, continue remotely */
676 if (ac
->local_dn
== NULL
) {
677 /* Do the remote request. */
678 return ldb_next_remote_request(ac
->module
, ac
->remote_req
);
681 /* Prepare the local operation */
682 ret
= ldb_build_del_req(&local_req
, ldb
, ac
,
686 map_op_local_callback
,
688 LDB_REQ_SET_LOCATION(local_req
);
689 if (ret
!= LDB_SUCCESS
) {
690 return LDB_ERR_OPERATIONS_ERROR
;
692 return ldb_next_request(ac
->module
, local_req
);
695 /*****************************************************************************
697 *****************************************************************************/
699 /* Rename a record. */
700 int ldb_map_rename(struct ldb_module
*module
, struct ldb_request
*req
)
702 struct ldb_request
*search_req
;
703 struct ldb_context
*ldb
;
704 struct map_context
*ac
;
707 ldb
= ldb_module_get_ctx(module
);
709 /* Do not manipulate our control entries */
710 if (ldb_dn_is_special(req
->op
.rename
.olddn
)) {
711 return ldb_next_request(module
, req
);
714 /* No mapping requested (perhaps no DN mapping specified).
715 * Skip to next module */
716 if ((!ldb_dn_check_local(module
, req
->op
.rename
.olddn
)) &&
717 (!ldb_dn_check_local(module
, req
->op
.rename
.newdn
))) {
718 return ldb_next_request(module
, req
);
721 /* Rename into/out of the mapped partition requested, bail out */
722 if (!ldb_dn_check_local(module
, req
->op
.rename
.olddn
) ||
723 !ldb_dn_check_local(module
, req
->op
.rename
.newdn
)) {
724 return LDB_ERR_AFFECTS_MULTIPLE_DSAS
;
727 /* Prepare context and handle */
728 ac
= map_init_context(module
, req
);
730 return LDB_ERR_OPERATIONS_ERROR
;
733 /* Prepare the remote operation */
734 ret
= ldb_build_rename_req(&ac
->remote_req
, ldb
, ac
,
735 ldb_dn_map_local(module
, ac
, req
->op
.rename
.olddn
),
736 ldb_dn_map_local(module
, ac
, req
->op
.rename
.newdn
),
738 ac
, map_op_remote_callback
,
740 LDB_REQ_SET_LOCATION(ac
->remote_req
);
741 if (ret
!= LDB_SUCCESS
) {
742 return LDB_ERR_OPERATIONS_ERROR
;
745 /* No local db, just run the remote request */
746 if (!map_check_local_db(ac
->module
)) {
747 /* Do the remote request. */
748 return ldb_next_remote_request(ac
->module
, ac
->remote_req
);
751 /* Prepare the search operation */
752 ret
= map_search_self_req(&search_req
, ac
, req
->op
.rename
.olddn
);
753 if (ret
!= LDB_SUCCESS
) {
755 return LDB_ERR_OPERATIONS_ERROR
;
758 return ldb_next_request(module
, search_req
);
761 /* Rename the local record. */
762 static int map_rename_do_local(struct map_context
*ac
)
764 struct ldb_request
*local_req
;
765 struct ldb_context
*ldb
;
768 ldb
= ldb_module_get_ctx(ac
->module
);
770 /* No local record, continue remotely */
771 if (ac
->local_dn
== NULL
) {
772 /* Do the remote request. */
773 return ldb_next_remote_request(ac
->module
, ac
->remote_req
);
776 /* Prepare the local operation */
777 ret
= ldb_build_rename_req(&local_req
, ldb
, ac
,
778 ac
->req
->op
.rename
.olddn
,
779 ac
->req
->op
.rename
.newdn
,
782 map_rename_local_callback
,
784 LDB_REQ_SET_LOCATION(local_req
);
785 if (ret
!= LDB_SUCCESS
) {
786 return LDB_ERR_OPERATIONS_ERROR
;
789 return ldb_next_request(ac
->module
, local_req
);
792 static int map_rename_local_callback(struct ldb_request
*req
,
793 struct ldb_reply
*ares
)
795 struct ldb_context
*ldb
;
796 struct map_context
*ac
;
799 ac
= talloc_get_type(req
->context
, struct map_context
);
800 ldb
= ldb_module_get_ctx(ac
->module
);
803 return ldb_module_done(ac
->req
, NULL
, NULL
,
804 LDB_ERR_OPERATIONS_ERROR
);
806 if (ares
->error
!= LDB_SUCCESS
) {
807 return ldb_module_done(ac
->req
, ares
->controls
,
808 ares
->response
, ares
->error
);
811 if (ares
->type
!= LDB_REPLY_DONE
) {
812 ldb_asprintf_errstring(ldb
, "Invalid LDB reply type %d", ares
->type
);
813 return ldb_module_done(ac
->req
, NULL
, NULL
,
814 LDB_ERR_OPERATIONS_ERROR
);
817 /* proceed with next step */
818 ret
= map_rename_do_fixup(ac
);
819 if (ret
!= LDB_SUCCESS
) {
820 return ldb_module_done(ac
->req
, NULL
, NULL
,
821 LDB_ERR_OPERATIONS_ERROR
);
827 /* Update the local 'IS_MAPPED' attribute. */
828 static int map_rename_do_fixup(struct map_context
*ac
)
830 struct ldb_request
*local_req
;
832 /* Prepare the fixup operation */
833 /* TODO: use GUIDs here instead -- or skip it when GUIDs are used. */
834 local_req
= map_build_fixup_req(ac
,
835 ac
->req
->op
.rename
.newdn
,
836 ac
->remote_req
->op
.rename
.newdn
,
838 map_op_local_callback
);
839 if (local_req
== NULL
) {
840 return LDB_ERR_OPERATIONS_ERROR
;
843 return ldb_next_request(ac
->module
, local_req
);