4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Simo Sorce 2006
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/>.
28 * Component: ldb ldap backend
30 * Description: core files for LDAP backend
32 * Author: Andrew Tridgell
36 * - description: make the module use asynchronous calls
42 #include "system/filesys.h"
43 #include "system/time.h"
44 #include "ldb_module.h"
45 #include "ldb_private.h"
47 #define LDAP_DEPRECATED 1
55 struct ldb_module
*module
;
56 struct ldb_request
*req
;
58 struct lldb_private
*lldb
;
60 struct ldb_control
**controls
;
64 static int lldb_ldap_to_ldb(int err
) {
65 /* Ldap errors and ldb errors are defined to the same values */
70 convert a ldb_message structure to a list of LDAPMod structures
71 ready for ldap_add() or ldap_modify()
73 static LDAPMod
**lldb_msg_to_mods(void *mem_ctx
, const struct ldb_message
*msg
, int use_flags
)
79 /* allocate maximum number of elements needed */
80 mods
= talloc_array(mem_ctx
, LDAPMod
*, msg
->num_elements
+1);
87 for (i
=0;i
<msg
->num_elements
;i
++) {
88 const struct ldb_message_element
*el
= &msg
->elements
[i
];
90 mods
[num_mods
] = talloc(mods
, LDAPMod
);
91 if (!mods
[num_mods
]) {
94 mods
[num_mods
+1] = NULL
;
95 mods
[num_mods
]->mod_op
= LDAP_MOD_BVALUES
;
97 switch (el
->flags
& LDB_FLAG_MOD_MASK
) {
98 case LDB_FLAG_MOD_ADD
:
99 mods
[num_mods
]->mod_op
|= LDAP_MOD_ADD
;
101 case LDB_FLAG_MOD_DELETE
:
102 mods
[num_mods
]->mod_op
|= LDAP_MOD_DELETE
;
104 case LDB_FLAG_MOD_REPLACE
:
105 mods
[num_mods
]->mod_op
|= LDAP_MOD_REPLACE
;
109 mods
[num_mods
]->mod_type
= discard_const_p(char, el
->name
);
110 mods
[num_mods
]->mod_vals
.modv_bvals
= talloc_array(mods
[num_mods
],
113 if (!mods
[num_mods
]->mod_vals
.modv_bvals
) {
117 for (j
=0;j
<el
->num_values
;j
++) {
118 mods
[num_mods
]->mod_vals
.modv_bvals
[j
] = talloc(mods
[num_mods
]->mod_vals
.modv_bvals
,
120 if (!mods
[num_mods
]->mod_vals
.modv_bvals
[j
]) {
123 mods
[num_mods
]->mod_vals
.modv_bvals
[j
]->bv_val
= (char *)el
->values
[j
].data
;
124 mods
[num_mods
]->mod_vals
.modv_bvals
[j
]->bv_len
= el
->values
[j
].length
;
126 mods
[num_mods
]->mod_vals
.modv_bvals
[j
] = NULL
;
138 add a single set of ldap message values to a ldb_message
140 static int lldb_add_msg_attr(struct ldb_context
*ldb
,
141 struct ldb_message
*msg
,
142 const char *attr
, struct berval
**bval
)
145 struct ldb_message_element
*el
;
147 count
= ldap_count_values_len(bval
);
153 el
= talloc_realloc(msg
, msg
->elements
, struct ldb_message_element
,
154 msg
->num_elements
+ 1);
162 el
= &msg
->elements
[msg
->num_elements
];
164 el
->name
= talloc_strdup(msg
->elements
, attr
);
172 el
->values
= talloc_array(msg
->elements
, struct ldb_val
, count
);
178 for (i
=0;i
<count
;i
++) {
179 /* we have to ensure this is null terminated so that
180 ldb_msg_find_attr_as_string() can work */
181 el
->values
[i
].data
= talloc_size(el
->values
, bval
[i
]->bv_len
+1);
182 if (!el
->values
[i
].data
) {
186 memcpy(el
->values
[i
].data
, bval
[i
]->bv_val
, bval
[i
]->bv_len
);
187 el
->values
[i
].data
[bval
[i
]->bv_len
] = 0;
188 el
->values
[i
].length
= bval
[i
]->bv_len
;
198 search for matching records
200 static int lldb_search(struct lldb_context
*lldb_ac
)
202 struct ldb_context
*ldb
;
203 struct lldb_private
*lldb
= lldb_ac
->lldb
;
204 struct ldb_module
*module
= lldb_ac
->module
;
205 struct ldb_request
*req
= lldb_ac
->req
;
212 ldb
= ldb_module_get_ctx(module
);
214 if (!req
->callback
|| !req
->context
) {
215 ldb_set_errstring(ldb
, "Async interface called with NULL callback function or NULL context");
216 return LDB_ERR_OPERATIONS_ERROR
;
219 if (req
->op
.search
.tree
== NULL
) {
220 ldb_set_errstring(ldb
, "Invalid expression parse tree");
221 return LDB_ERR_OPERATIONS_ERROR
;
224 if (req
->controls
!= NULL
) {
225 ldb_debug(ldb
, LDB_DEBUG_WARNING
, "Controls are not yet supported by ldb_ldap backend!");
228 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
230 search_base
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.search
.base
);
231 if (req
->op
.search
.base
== NULL
) {
232 search_base
= talloc_strdup(lldb_ac
, "");
234 if (search_base
== NULL
) {
235 return LDB_ERR_OPERATIONS_ERROR
;
238 expression
= ldb_filter_from_tree(lldb_ac
, req
->op
.search
.tree
);
239 if (expression
== NULL
) {
240 return LDB_ERR_OPERATIONS_ERROR
;
243 switch (req
->op
.search
.scope
) {
245 ldap_scope
= LDAP_SCOPE_BASE
;
247 case LDB_SCOPE_ONELEVEL
:
248 ldap_scope
= LDAP_SCOPE_ONELEVEL
;
251 ldap_scope
= LDAP_SCOPE_SUBTREE
;
255 tv
.tv_sec
= req
->timeout
;
258 ret
= ldap_search_ext(lldb
->ldap
, search_base
, ldap_scope
,
260 discard_const_p(char *, req
->op
.search
.attrs
),
268 if (ret
!= LDAP_SUCCESS
) {
269 ldb_set_errstring(ldb
, ldap_err2string(ret
));
272 return lldb_ldap_to_ldb(ret
);
278 static int lldb_add(struct lldb_context
*lldb_ac
)
280 struct ldb_context
*ldb
;
281 struct lldb_private
*lldb
= lldb_ac
->lldb
;
282 struct ldb_module
*module
= lldb_ac
->module
;
283 struct ldb_request
*req
= lldb_ac
->req
;
288 ldb
= ldb_module_get_ctx(module
);
290 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
292 mods
= lldb_msg_to_mods(lldb_ac
, req
->op
.add
.message
, 0);
294 return LDB_ERR_OPERATIONS_ERROR
;
297 dn
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.add
.message
->dn
);
299 return LDB_ERR_OPERATIONS_ERROR
;
302 ret
= ldap_add_ext(lldb
->ldap
, dn
, mods
,
307 if (ret
!= LDAP_SUCCESS
) {
308 ldb_set_errstring(ldb
, ldap_err2string(ret
));
311 return lldb_ldap_to_ldb(ret
);
317 static int lldb_modify(struct lldb_context
*lldb_ac
)
319 struct ldb_context
*ldb
;
320 struct lldb_private
*lldb
= lldb_ac
->lldb
;
321 struct ldb_module
*module
= lldb_ac
->module
;
322 struct ldb_request
*req
= lldb_ac
->req
;
327 ldb
= ldb_module_get_ctx(module
);
329 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
331 mods
= lldb_msg_to_mods(lldb_ac
, req
->op
.mod
.message
, 1);
333 return LDB_ERR_OPERATIONS_ERROR
;
336 dn
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.mod
.message
->dn
);
338 return LDB_ERR_OPERATIONS_ERROR
;
341 ret
= ldap_modify_ext(lldb
->ldap
, dn
, mods
,
346 if (ret
!= LDAP_SUCCESS
) {
347 ldb_set_errstring(ldb
, ldap_err2string(ret
));
350 return lldb_ldap_to_ldb(ret
);
356 static int lldb_delete(struct lldb_context
*lldb_ac
)
358 struct ldb_context
*ldb
;
359 struct lldb_private
*lldb
= lldb_ac
->lldb
;
360 struct ldb_module
*module
= lldb_ac
->module
;
361 struct ldb_request
*req
= lldb_ac
->req
;
365 ldb
= ldb_module_get_ctx(module
);
367 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
369 dnstr
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.del
.dn
);
371 ret
= ldap_delete_ext(lldb
->ldap
, dnstr
,
376 if (ret
!= LDAP_SUCCESS
) {
377 ldb_set_errstring(ldb
, ldap_err2string(ret
));
380 return lldb_ldap_to_ldb(ret
);
386 static int lldb_rename(struct lldb_context
*lldb_ac
)
388 struct ldb_context
*ldb
;
389 struct lldb_private
*lldb
= lldb_ac
->lldb
;
390 struct ldb_module
*module
= lldb_ac
->module
;
391 struct ldb_request
*req
= lldb_ac
->req
;
392 const char *rdn_name
;
393 const struct ldb_val
*rdn_val
;
399 ldb
= ldb_module_get_ctx(module
);
401 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
403 old_dn
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.rename
.olddn
);
404 if (old_dn
== NULL
) {
405 return LDB_ERR_OPERATIONS_ERROR
;
408 rdn_name
= ldb_dn_get_rdn_name(req
->op
.rename
.newdn
);
409 rdn_val
= ldb_dn_get_rdn_val(req
->op
.rename
.newdn
);
411 if ((rdn_name
!= NULL
) && (rdn_val
!= NULL
)) {
412 newrdn
= talloc_asprintf(lldb_ac
, "%s=%s", rdn_name
,
413 rdn_val
->length
> 0 ? ldb_dn_escape_value(lldb
, *rdn_val
) : "");
415 newrdn
= talloc_strdup(lldb_ac
, "");
418 return LDB_ERR_OPERATIONS_ERROR
;
421 parentdn
= ldb_dn_alloc_linearized(lldb_ac
, ldb_dn_get_parent(lldb_ac
, req
->op
.rename
.newdn
));
423 return LDB_ERR_OPERATIONS_ERROR
;
426 ret
= ldap_rename(lldb
->ldap
, old_dn
, newrdn
, parentdn
,
430 if (ret
!= LDAP_SUCCESS
) {
431 ldb_set_errstring(ldb
, ldap_err2string(ret
));
434 return lldb_ldap_to_ldb(ret
);
437 static int lldb_start_trans(struct ldb_module
*module
)
439 /* TODO implement a local transaction mechanism here */
444 static int lldb_end_trans(struct ldb_module
*module
)
446 /* TODO implement a local transaction mechanism here */
451 static int lldb_del_trans(struct ldb_module
*module
)
453 /* TODO implement a local transaction mechanism here */
458 static void lldb_request_done(struct lldb_context
*ac
,
459 struct ldb_control
**ctrls
, int error
)
461 struct ldb_request
*req
;
462 struct ldb_reply
*ares
;
466 ares
= talloc_zero(req
, struct ldb_reply
);
468 ldb_oom(ldb_module_get_ctx(ac
->module
));
469 req
->callback(req
, NULL
);
472 ares
->type
= LDB_REPLY_DONE
;
473 ares
->controls
= talloc_steal(ares
, ctrls
);
476 req
->callback(req
, ares
);
479 /* return false if the request is still in progress
480 * return true if the request is completed
482 static bool lldb_parse_result(struct lldb_context
*ac
, LDAPMessage
*result
)
484 struct ldb_context
*ldb
;
485 struct lldb_private
*lldb
= ac
->lldb
;
486 LDAPControl
**serverctrlsp
= NULL
;
487 char **referralsp
= NULL
;
488 char *matcheddnp
= NULL
;
489 char *errmsgp
= NULL
;
492 struct ldb_message
*ldbmsg
;
494 bool callback_failed
;
500 ldb
= ldb_module_get_ctx(ac
->module
);
502 type
= ldap_msgtype(result
);
503 callback_failed
= false;
504 request_done
= false;
507 case LDAP_RES_SEARCH_ENTRY
:
509 msg
= ldap_first_entry(lldb
->ldap
, result
);
511 BerElement
*berptr
= NULL
;
514 ldbmsg
= ldb_msg_new(ac
);
517 ret
= LDB_ERR_OPERATIONS_ERROR
;
521 dn
= ldap_get_dn(lldb
->ldap
, msg
);
525 ret
= LDB_ERR_OPERATIONS_ERROR
;
528 ldbmsg
->dn
= ldb_dn_new(ldbmsg
, ldb
, dn
);
529 if ( ! ldb_dn_validate(ldbmsg
->dn
)) {
530 ldb_asprintf_errstring(ldb
, "Invalid DN '%s' in reply", dn
);
532 ret
= LDB_ERR_OPERATIONS_ERROR
;
538 ldbmsg
->num_elements
= 0;
539 ldbmsg
->elements
= NULL
;
541 /* loop over all attributes */
542 for (attr
=ldap_first_attribute(lldb
->ldap
, msg
, &berptr
);
544 attr
=ldap_next_attribute(lldb
->ldap
, msg
, berptr
)) {
545 struct berval
**bval
;
546 bval
= ldap_get_values_len(lldb
->ldap
, msg
, attr
);
549 lldb_add_msg_attr(ldb
, ldbmsg
, attr
, bval
);
550 ldap_value_free_len(bval
);
553 if (berptr
) ber_free(berptr
, 0);
555 ret
= ldb_module_send_entry(ac
->req
, ldbmsg
, NULL
/* controls not yet supported */);
556 if (ret
!= LDB_SUCCESS
) {
557 ldb_asprintf_errstring(ldb
, "entry send failed: %s",
559 callback_failed
= true;
562 ret
= LDB_ERR_OPERATIONS_ERROR
;
566 case LDAP_RES_SEARCH_REFERENCE
:
568 ret
= ldap_parse_reference(lldb
->ldap
, result
,
569 &referralsp
, &serverctrlsp
, 0);
570 if (ret
!= LDAP_SUCCESS
) {
571 ldb_asprintf_errstring(ldb
, "ldap reference parse error: %s : %s",
572 ldap_err2string(ret
), errmsgp
);
573 ret
= LDB_ERR_OPERATIONS_ERROR
;
576 if (referralsp
== NULL
) {
577 ldb_asprintf_errstring(ldb
, "empty ldap referrals list");
578 ret
= LDB_ERR_PROTOCOL_ERROR
;
582 for (i
= 0; referralsp
[i
]; i
++) {
583 referral
= talloc_strdup(ac
, referralsp
[i
]);
585 ret
= ldb_module_send_referral(ac
->req
, referral
);
586 if (ret
!= LDB_SUCCESS
) {
587 ldb_asprintf_errstring(ldb
, "referral send failed: %s",
589 callback_failed
= true;
595 case LDAP_RES_SEARCH_RESULT
:
596 case LDAP_RES_MODIFY
:
598 case LDAP_RES_DELETE
:
601 if (ldap_parse_result(lldb
->ldap
, result
, &ret
,
602 &matcheddnp
, &errmsgp
,
603 &referralsp
, &serverctrlsp
, 0) != LDAP_SUCCESS
) {
604 ret
= LDB_ERR_OPERATIONS_ERROR
;
606 if (ret
!= LDB_SUCCESS
) {
607 ldb_asprintf_errstring(ldb
, "ldap parse error for type %d: %s : %s",
608 type
, ldap_err2string(ret
), errmsgp
);
612 if (serverctrlsp
!= NULL
) {
613 /* FIXME: transform the LDAPControl list into an ldb_control one */
621 ldb_asprintf_errstring(ldb
, "unknown ldap return type: %d", type
);
622 ret
= LDB_ERR_PROTOCOL_ERROR
;
626 if (ret
!= LDB_SUCCESS
) {
628 /* if the callback failed the caller will have freed the
629 * request. Just return and don't try to use it */
630 if (callback_failed
) {
632 /* tell lldb_wait to remove the request from the
635 goto free_and_return
;
642 lldb_request_done(ac
, ac
->controls
, ret
);
644 goto free_and_return
;
651 if (matcheddnp
) ldap_memfree(matcheddnp
);
652 if (errmsgp
&& *errmsgp
) {
653 ldb_set_errstring(ldb
, errmsgp
);
656 ldap_memfree(errmsgp
);
658 if (referralsp
) ldap_value_free(referralsp
);
659 if (serverctrlsp
) ldap_controls_free(serverctrlsp
);
661 ldap_msgfree(result
);
666 static void lldb_timeout(struct tevent_context
*ev
,
667 struct tevent_timer
*te
,
671 struct lldb_context
*ac
;
672 ac
= talloc_get_type(private_data
, struct lldb_context
);
674 lldb_request_done(ac
, NULL
, LDB_ERR_TIME_LIMIT_EXCEEDED
);
677 static void lldb_callback(struct tevent_context
*ev
,
678 struct tevent_timer
*te
,
682 struct lldb_context
*ac
;
683 struct tevent_timer
*lte
;
688 ac
= talloc_get_type(private_data
, struct lldb_context
);
691 lldb_request_done(ac
, NULL
, LDB_ERR_OPERATIONS_ERROR
);
697 lret
= ldap_result(ac
->lldb
->ldap
, ac
->msgid
, 0, &tv
, &result
);
702 lldb_request_done(ac
, NULL
, LDB_ERR_OPERATIONS_ERROR
);
706 if ( ! lldb_parse_result(ac
, result
)) {
715 lte
= tevent_add_timer(ev
, ac
, tv
, lldb_callback
, ac
);
717 lldb_request_done(ac
, NULL
, LDB_ERR_OPERATIONS_ERROR
);
721 static bool lldb_dn_is_special(struct ldb_request
*req
)
723 struct ldb_dn
*dn
= NULL
;
725 switch (req
->operation
) {
727 dn
= req
->op
.add
.message
->dn
;
730 dn
= req
->op
.mod
.message
->dn
;
736 dn
= req
->op
.rename
.olddn
;
742 if (dn
&& ldb_dn_is_special(dn
)) {
748 static void lldb_auto_done_callback(struct tevent_context
*ev
,
749 struct tevent_timer
*te
,
753 struct lldb_context
*ac
;
755 ac
= talloc_get_type(private_data
, struct lldb_context
);
756 lldb_request_done(ac
, NULL
, LDB_SUCCESS
);
759 static int lldb_handle_request(struct ldb_module
*module
, struct ldb_request
*req
)
761 struct ldb_context
*ldb
;
762 struct lldb_private
*lldb
;
763 struct lldb_context
*ac
;
764 struct tevent_context
*ev
;
765 struct tevent_timer
*te
;
769 lldb
= talloc_get_type(ldb_module_get_private(module
), struct lldb_private
);
770 ldb
= ldb_module_get_ctx(module
);
772 if (req
->starttime
== 0 || req
->timeout
== 0) {
773 ldb_set_errstring(ldb
, "Invalid timeout settings");
774 return LDB_ERR_TIME_LIMIT_EXCEEDED
;
777 ev
= ldb_get_event_context(ldb
);
779 return LDB_ERR_OPERATIONS_ERROR
;
782 ac
= talloc_zero(ldb
, struct lldb_context
);
784 ldb_set_errstring(ldb
, "Out of Memory");
785 return LDB_ERR_OPERATIONS_ERROR
;
793 if (lldb_dn_is_special(req
)) {
796 te
= tevent_add_timer(ev
, ac
, tv
,
797 lldb_auto_done_callback
, ac
);
799 return LDB_ERR_OPERATIONS_ERROR
;
805 switch (ac
->req
->operation
) {
807 ret
= lldb_search(ac
);
813 ret
= lldb_modify(ac
);
816 ret
= lldb_delete(ac
);
819 ret
= lldb_rename(ac
);
822 /* no other op supported */
823 ret
= LDB_ERR_PROTOCOL_ERROR
;
827 if (ret
!= LDB_SUCCESS
) {
828 lldb_request_done(ac
, NULL
, ret
);
834 te
= tevent_add_timer(ev
, ac
, tv
, lldb_callback
, ac
);
836 return LDB_ERR_OPERATIONS_ERROR
;
840 tv
.tv_sec
= req
->starttime
+ req
->timeout
;
842 te
= tevent_add_timer(ev
, ac
, tv
, lldb_timeout
, ac
);
844 return LDB_ERR_OPERATIONS_ERROR
;
850 static const struct ldb_module_ops lldb_ops
= {
852 .search
= lldb_handle_request
,
853 .add
= lldb_handle_request
,
854 .modify
= lldb_handle_request
,
855 .del
= lldb_handle_request
,
856 .rename
= lldb_handle_request
,
857 .request
= lldb_handle_request
,
858 .start_transaction
= lldb_start_trans
,
859 .end_transaction
= lldb_end_trans
,
860 .del_transaction
= lldb_del_trans
,
864 static int lldb_destructor(struct lldb_private
*lldb
)
866 ldap_unbind(lldb
->ldap
);
872 optionally perform a bind
874 static int lldb_bind(struct ldb_module
*module
,
875 const char *options
[])
877 const char *bind_mechanism
;
878 struct lldb_private
*lldb
;
879 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
882 bind_mechanism
= ldb_options_find(ldb
, options
, "bindMech");
883 if (bind_mechanism
== NULL
) {
888 lldb
= talloc_get_type(ldb_module_get_private(module
), struct lldb_private
);
890 if (strcmp(bind_mechanism
, "simple") == 0) {
891 const char *bind_id
, *bind_secret
;
893 bind_id
= ldb_options_find(ldb
, options
, "bindID");
894 bind_secret
= ldb_options_find(ldb
, options
, "bindSecret");
895 if (bind_id
== NULL
|| bind_secret
== NULL
) {
896 ldb_asprintf_errstring(ldb
, "simple bind requires bindID and bindSecret");
897 return LDB_ERR_OPERATIONS_ERROR
;
900 ret
= ldap_simple_bind_s(lldb
->ldap
, bind_id
, bind_secret
);
901 if (ret
!= LDAP_SUCCESS
) {
902 ldb_asprintf_errstring(ldb
, "bind failed: %s", ldap_err2string(ret
));
908 ldb_asprintf_errstring(ldb
, "bind failed: unknown mechanism %s", bind_mechanism
);
909 return LDB_ERR_INAPPROPRIATE_AUTHENTICATION
;
913 connect to the database
915 static int lldb_connect(struct ldb_context
*ldb
,
918 const char *options
[],
919 struct ldb_module
**_module
)
921 struct ldb_module
*module
;
922 struct lldb_private
*lldb
;
926 module
= ldb_module_new(ldb
, ldb
, "ldb_ldap backend", &lldb_ops
);
927 if (!module
) return LDB_ERR_OPERATIONS_ERROR
;
929 lldb
= talloc_zero(module
, struct lldb_private
);
934 ldb_module_set_private(module
, lldb
);
936 ret
= ldap_initialize(&lldb
->ldap
, url
);
937 if (ret
!= LDAP_SUCCESS
) {
938 ldb_debug(ldb
, LDB_DEBUG_FATAL
, "ldap_initialize failed for URL '%s' - %s",
939 url
, ldap_err2string(ret
));
943 talloc_set_destructor(lldb
, lldb_destructor
);
945 ret
= ldap_set_option(lldb
->ldap
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
946 if (ret
!= LDAP_SUCCESS
) {
947 ldb_debug(ldb
, LDB_DEBUG_FATAL
, "ldap_set_option failed - %s",
948 ldap_err2string(ret
));
954 ret
= lldb_bind(module
, options
);
955 if (ret
!= LDB_SUCCESS
) {
964 return LDB_ERR_OPERATIONS_ERROR
;
968 initialise the module
970 int ldb_ldap_init(const char *version
)
973 const char *names
[] = { "ldap", "ldaps", "ldapi", NULL
};
974 LDB_MODULE_CHECK_VERSION(version
);
975 for (i
=0; names
[i
]; i
++) {
976 ret
= ldb_register_backend(names
[i
], lldb_connect
, false);
977 if (ret
!= LDB_SUCCESS
) {