2 ldb database library - ildap backend
4 Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 * Component: ldb ildap backend
31 * Description: This is a ldb backend for the internal ldap
32 * client library in Samba4. By using this backend we are
33 * independent of a system ldap library
35 * Author: Andrew Tridgell
39 * - description: make the module use asyncronous calls
46 #include "ldb/include/includes.h"
48 #include "lib/events/events.h"
49 #include "libcli/ldap/ldap.h"
50 #include "libcli/ldap/ldap_client.h"
51 #include "auth/auth.h"
52 #include "auth/credentials/credentials.h"
55 struct ldap_connection
*ldap
;
56 struct ldb_module
*module
;
60 struct ildb_private
*ildb
;
61 struct ldb_handle
*handle
;
62 struct ldap_request
*req
;
64 int (*callback
)(struct ldb_context
*, void *, struct ldb_reply
*);
68 convert a ldb_message structure to a list of ldap_mod structures
69 ready for ildap_add() or ildap_modify()
71 static struct ldap_mod
**ildb_msg_to_mods(void *mem_ctx
, int *num_mods
,
72 const struct ldb_message
*msg
, int use_flags
)
74 struct ldap_mod
**mods
;
78 /* allocate maximum number of elements needed */
79 mods
= talloc_array(mem_ctx
, struct ldap_mod
*, msg
->num_elements
+1);
86 for (i
= 0; i
< msg
->num_elements
; i
++) {
87 const struct ldb_message_element
*el
= &msg
->elements
[i
];
89 mods
[n
] = talloc(mods
, struct ldap_mod
);
95 mods
[n
]->attrib
= *el
;
97 switch (el
->flags
& LDB_FLAG_MOD_MASK
) {
98 case LDB_FLAG_MOD_ADD
:
99 mods
[n
]->type
= LDAP_MODIFY_ADD
;
101 case LDB_FLAG_MOD_DELETE
:
102 mods
[n
]->type
= LDAP_MODIFY_DELETE
;
104 case LDB_FLAG_MOD_REPLACE
:
105 mods
[n
]->type
= LDAP_MODIFY_REPLACE
;
122 map an ildap NTSTATUS to a ldb error code
124 static int ildb_map_error(struct ildb_private
*ildb
, NTSTATUS status
)
126 if (NT_STATUS_IS_OK(status
)) {
129 ldb_set_errstring(ildb
->module
->ldb
, ldap_errstr(ildb
->ldap
, status
));
130 if (NT_STATUS_IS_LDAP(status
)) {
131 return NT_STATUS_LDAP_CODE(status
);
133 return LDB_ERR_OPERATIONS_ERROR
;
136 static void ildb_request_timeout(struct event_context
*ev
, struct timed_event
*te
,
137 struct timeval t
, void *private_data
)
139 struct ildb_context
*ac
= talloc_get_type(private_data
, struct ildb_context
);
140 struct ldb_handle
*handle
= ac
->handle
;
142 if (ac
->req
->state
== LDAP_REQUEST_PENDING
) {
143 DLIST_REMOVE(ac
->req
->conn
->pending
, ac
->req
);
146 handle
->status
= LDB_ERR_TIME_LIMIT_EXCEEDED
;
151 static void ildb_callback(struct ldap_request
*req
)
153 struct ildb_context
*ac
= talloc_get_type(req
->async
.private_data
, struct ildb_context
);
154 struct ldb_handle
*handle
= ac
->handle
;
155 struct ildb_private
*ildb
= ac
->ildb
;
159 handle
->status
= LDB_SUCCESS
;
161 if (!NT_STATUS_IS_OK(req
->status
)) {
162 handle
->status
= ildb_map_error(ildb
, req
->status
);
166 if (req
->num_replies
< 1) {
167 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
173 case LDAP_TAG_ModifyRequest
:
174 if (req
->replies
[0]->type
!= LDAP_TAG_ModifyResponse
) {
175 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
178 status
= ldap_check_response(req
->conn
, &req
->replies
[0]->r
.GeneralResult
);
179 handle
->status
= ildb_map_error(ildb
, status
);
180 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
181 /* FIXME: build a corresponding ares to pass on */
182 handle
->status
= ac
->callback(ac
->ildb
->module
->ldb
, ac
->context
, NULL
);
184 handle
->state
= LDB_ASYNC_DONE
;
187 case LDAP_TAG_AddRequest
:
188 if (req
->replies
[0]->type
!= LDAP_TAG_AddResponse
) {
189 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
192 status
= ldap_check_response(req
->conn
, &req
->replies
[0]->r
.GeneralResult
);
193 handle
->status
= ildb_map_error(ildb
, status
);
194 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
195 /* FIXME: build a corresponding ares to pass on */
196 handle
->status
= ac
->callback(ac
->ildb
->module
->ldb
, ac
->context
, NULL
);
198 handle
->state
= LDB_ASYNC_DONE
;
201 case LDAP_TAG_DelRequest
:
202 if (req
->replies
[0]->type
!= LDAP_TAG_DelResponse
) {
203 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
206 status
= ldap_check_response(req
->conn
, &req
->replies
[0]->r
.GeneralResult
);
207 handle
->status
= ildb_map_error(ildb
, status
);
208 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
209 /* FIXME: build a corresponding ares to pass on */
210 handle
->status
= ac
->callback(ac
->ildb
->module
->ldb
, ac
->context
, NULL
);
212 handle
->state
= LDB_ASYNC_DONE
;
215 case LDAP_TAG_ModifyDNRequest
:
216 if (req
->replies
[0]->type
!= LDAP_TAG_ModifyDNResponse
) {
217 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
220 status
= ldap_check_response(req
->conn
, &req
->replies
[0]->r
.GeneralResult
);
221 handle
->status
= ildb_map_error(ildb
, status
);
222 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
223 /* FIXME: build a corresponding ares to pass on */
224 handle
->status
= ac
->callback(ac
->ildb
->module
->ldb
, ac
->context
, NULL
);
226 handle
->state
= LDB_ASYNC_DONE
;
229 case LDAP_TAG_SearchRequest
:
230 /* loop over all messages */
231 for (i
= 0; i
< req
->num_replies
; i
++) {
232 struct ldap_SearchResEntry
*search
;
233 struct ldb_reply
*ares
= NULL
;
234 struct ldap_message
*msg
;
237 ares
= talloc_zero(ac
, struct ldb_reply
);
239 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
243 msg
= req
->replies
[i
];
246 case LDAP_TAG_SearchResultDone
:
248 status
= ldap_check_response(req
->conn
, &msg
->r
.GeneralResult
);
249 if (!NT_STATUS_IS_OK(status
)) {
250 handle
->status
= ildb_map_error(ildb
, status
);
254 ares
->controls
= talloc_move(ares
, &msg
->controls
);
255 if (msg
->r
.SearchResultDone
.resultcode
) {
256 if (msg
->r
.SearchResultDone
.errormessage
) {
257 ldb_set_errstring(ac
->ildb
->module
->ldb
, msg
->r
.SearchResultDone
.errormessage
);
261 handle
->status
= msg
->r
.SearchResultDone
.resultcode
;
262 handle
->state
= LDB_ASYNC_DONE
;
263 ares
->type
= LDB_REPLY_DONE
;
266 case LDAP_TAG_SearchResultEntry
:
269 ares
->message
= ldb_msg_new(ares
);
270 if (!ares
->message
) {
271 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
275 search
= &(msg
->r
.SearchResultEntry
);
277 ares
->message
->dn
= ldb_dn_new(ares
->message
, ac
->ildb
->module
->ldb
, search
->dn
);
278 if ( ! ldb_dn_validate(ares
->message
->dn
)) {
279 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
282 ares
->message
->num_elements
= search
->num_attributes
;
283 ares
->message
->elements
= talloc_move(ares
->message
,
284 &search
->attributes
);
286 handle
->status
= LDB_SUCCESS
;
287 handle
->state
= LDB_ASYNC_PENDING
;
288 ares
->type
= LDB_REPLY_ENTRY
;
291 case LDAP_TAG_SearchResultReference
:
293 ares
->referral
= talloc_strdup(ares
, msg
->r
.SearchResultReference
.referral
);
295 handle
->status
= LDB_SUCCESS
;
296 handle
->state
= LDB_ASYNC_PENDING
;
297 ares
->type
= LDB_REPLY_REFERRAL
;
301 /* TAG not handled, fail ! */
302 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
306 ret
= ac
->callback(ac
->ildb
->module
->ldb
, ac
->context
, ares
);
308 handle
->status
= ret
;
312 talloc_free(req
->replies
);
314 req
->num_replies
= 0;
319 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
324 static struct ildb_context
*init_ildb_handle(struct ildb_private
*ildb
,
325 struct ldb_request
*req
)
327 struct ildb_context
*ildb_ac
;
328 struct ldb_handle
*h
;
330 h
= talloc_zero(req
, struct ldb_handle
);
332 ldb_set_errstring(ildb
->module
->ldb
, "Out of Memory");
336 h
->module
= ildb
->module
;
338 ildb_ac
= talloc(h
, struct ildb_context
);
339 if (ildb_ac
== NULL
) {
340 ldb_set_errstring(ildb
->module
->ldb
, "Out of Memory");
345 h
->private_data
= ildb_ac
;
347 h
->state
= LDB_ASYNC_INIT
;
348 h
->status
= LDB_SUCCESS
;
350 ildb_ac
->ildb
= ildb
;
352 ildb_ac
->context
= req
->context
;
353 ildb_ac
->callback
= req
->callback
;
359 static int ildb_request_send(struct ildb_private
*ildb
, struct ldap_message
*msg
, struct ldb_request
*r
)
361 struct ildb_context
*ildb_ac
= init_ildb_handle(ildb
, r
);
362 struct ldap_request
*req
;
365 return LDB_ERR_OPERATIONS_ERROR
;
368 req
= ldap_request_send(ildb
->ldap
, msg
);
370 ldb_set_errstring(ildb
->module
->ldb
, "async send request failed");
371 return LDB_ERR_OPERATIONS_ERROR
;
373 ildb_ac
->req
= talloc_steal(ildb_ac
, req
);
376 ldb_set_errstring(ildb
->module
->ldb
, "connection to remote LDAP server dropped?");
377 return LDB_ERR_OPERATIONS_ERROR
;
380 talloc_free(req
->time_event
);
381 req
->time_event
= NULL
;
383 req
->time_event
= event_add_timed(req
->conn
->event
.event_ctx
, ildb_ac
,
384 timeval_current_ofs(r
->timeout
, 0),
385 ildb_request_timeout
, ildb_ac
);
388 req
->async
.fn
= ildb_callback
;
389 req
->async
.private_data
= ildb_ac
;
394 static int ildb_request_noop(struct ildb_private
*ildb
, struct ldb_request
*req
)
396 struct ildb_context
*ildb_ac
= init_ildb_handle(ildb
, req
);
397 int ret
= LDB_SUCCESS
;
400 return LDB_ERR_OPERATIONS_ERROR
;
403 if (ildb_ac
->callback
) {
404 ret
= ildb_ac
->callback(ildb
->module
->ldb
, ildb_ac
->context
, NULL
);
406 ildb_ac
->handle
->state
= LDB_ASYNC_DONE
;
411 search for matching records using an asynchronous function
413 static int ildb_search(struct ldb_module
*module
, struct ldb_request
*req
)
415 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
416 struct ldap_message
*msg
;
421 if (!req
->callback
|| !req
->context
) {
422 ldb_set_errstring(module
->ldb
, "Async interface called with NULL callback function or NULL context");
423 return LDB_ERR_OPERATIONS_ERROR
;
426 if (req
->op
.search
.tree
== NULL
) {
427 ldb_set_errstring(module
->ldb
, "Invalid expression parse tree");
428 return LDB_ERR_OPERATIONS_ERROR
;
431 msg
= new_ldap_message(req
);
433 ldb_set_errstring(module
->ldb
, "Out of Memory");
434 return LDB_ERR_OPERATIONS_ERROR
;
437 msg
->type
= LDAP_TAG_SearchRequest
;
439 if (req
->op
.search
.base
== NULL
) {
440 msg
->r
.SearchRequest
.basedn
= talloc_strdup(msg
, "");
442 msg
->r
.SearchRequest
.basedn
= ldb_dn_alloc_linearized(msg
, req
->op
.search
.base
);
444 if (msg
->r
.SearchRequest
.basedn
== NULL
) {
445 ldb_set_errstring(module
->ldb
, "Unable to determine baseDN");
447 return LDB_ERR_OPERATIONS_ERROR
;
450 if (req
->op
.search
.scope
== LDB_SCOPE_DEFAULT
) {
451 msg
->r
.SearchRequest
.scope
= LDB_SCOPE_SUBTREE
;
453 msg
->r
.SearchRequest
.scope
= req
->op
.search
.scope
;
456 msg
->r
.SearchRequest
.deref
= LDAP_DEREFERENCE_NEVER
;
457 msg
->r
.SearchRequest
.timelimit
= 0;
458 msg
->r
.SearchRequest
.sizelimit
= 0;
459 msg
->r
.SearchRequest
.attributesonly
= 0;
460 msg
->r
.SearchRequest
.tree
= discard_const(req
->op
.search
.tree
);
462 for (n
= 0; req
->op
.search
.attrs
&& req
->op
.search
.attrs
[n
]; n
++) /* noop */ ;
463 msg
->r
.SearchRequest
.num_attributes
= n
;
464 msg
->r
.SearchRequest
.attributes
= discard_const(req
->op
.search
.attrs
);
465 msg
->controls
= req
->controls
;
467 return ildb_request_send(ildb
, msg
, req
);
473 static int ildb_add(struct ldb_module
*module
, struct ldb_request
*req
)
475 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
476 struct ldap_message
*msg
;
477 struct ldap_mod
**mods
;
482 /* ignore ltdb specials */
483 if (ldb_dn_is_special(req
->op
.add
.message
->dn
)) {
484 return ildb_request_noop(ildb
, req
);
487 msg
= new_ldap_message(req
);
489 return LDB_ERR_OPERATIONS_ERROR
;
492 msg
->type
= LDAP_TAG_AddRequest
;
494 msg
->r
.AddRequest
.dn
= ldb_dn_alloc_linearized(msg
, req
->op
.add
.message
->dn
);
495 if (msg
->r
.AddRequest
.dn
== NULL
) {
497 return LDB_ERR_INVALID_DN_SYNTAX
;
500 mods
= ildb_msg_to_mods(msg
, &n
, req
->op
.add
.message
, 0);
503 return LDB_ERR_OPERATIONS_ERROR
;
506 msg
->r
.AddRequest
.num_attributes
= n
;
507 msg
->r
.AddRequest
.attributes
= talloc_array(msg
, struct ldb_message_element
, n
);
508 if (msg
->r
.AddRequest
.attributes
== NULL
) {
510 return LDB_ERR_OPERATIONS_ERROR
;
513 for (i
= 0; i
< n
; i
++) {
514 msg
->r
.AddRequest
.attributes
[i
] = mods
[i
]->attrib
;
517 return ildb_request_send(ildb
, msg
, req
);
523 static int ildb_modify(struct ldb_module
*module
, struct ldb_request
*req
)
525 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
526 struct ldap_message
*msg
;
527 struct ldap_mod
**mods
;
532 /* ignore ltdb specials */
533 if (ldb_dn_is_special(req
->op
.mod
.message
->dn
)) {
534 return ildb_request_noop(ildb
, req
);
537 msg
= new_ldap_message(req
);
539 return LDB_ERR_OPERATIONS_ERROR
;
542 msg
->type
= LDAP_TAG_ModifyRequest
;
544 msg
->r
.ModifyRequest
.dn
= ldb_dn_alloc_linearized(msg
, req
->op
.mod
.message
->dn
);
545 if (msg
->r
.ModifyRequest
.dn
== NULL
) {
547 return LDB_ERR_INVALID_DN_SYNTAX
;
550 mods
= ildb_msg_to_mods(msg
, &n
, req
->op
.mod
.message
, 1);
553 return LDB_ERR_OPERATIONS_ERROR
;
556 msg
->r
.ModifyRequest
.num_mods
= n
;
557 msg
->r
.ModifyRequest
.mods
= talloc_array(msg
, struct ldap_mod
, n
);
558 if (msg
->r
.ModifyRequest
.mods
== NULL
) {
560 return LDB_ERR_OPERATIONS_ERROR
;
563 for (i
= 0; i
< n
; i
++) {
564 msg
->r
.ModifyRequest
.mods
[i
] = *mods
[i
];
567 return ildb_request_send(ildb
, msg
, req
);
573 static int ildb_delete(struct ldb_module
*module
, struct ldb_request
*req
)
575 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
576 struct ldap_message
*msg
;
580 /* ignore ltdb specials */
581 if (ldb_dn_is_special(req
->op
.del
.dn
)) {
582 return ildb_request_noop(ildb
, req
);
585 msg
= new_ldap_message(req
);
587 return LDB_ERR_OPERATIONS_ERROR
;
590 msg
->type
= LDAP_TAG_DelRequest
;
592 msg
->r
.DelRequest
.dn
= ldb_dn_alloc_linearized(msg
, req
->op
.del
.dn
);
593 if (msg
->r
.DelRequest
.dn
== NULL
) {
595 return LDB_ERR_INVALID_DN_SYNTAX
;
598 return ildb_request_send(ildb
, msg
, req
);
604 static int ildb_rename(struct ldb_module
*module
, struct ldb_request
*req
)
606 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
607 struct ldap_message
*msg
;
611 /* ignore ltdb specials */
612 if (ldb_dn_is_special(req
->op
.rename
.olddn
) || ldb_dn_is_special(req
->op
.rename
.newdn
)) {
613 return ildb_request_noop(ildb
, req
);
616 msg
= new_ldap_message(req
);
618 return LDB_ERR_OPERATIONS_ERROR
;
621 msg
->type
= LDAP_TAG_ModifyDNRequest
;
622 msg
->r
.ModifyDNRequest
.dn
= ldb_dn_alloc_linearized(msg
, req
->op
.rename
.olddn
);
623 if (msg
->r
.ModifyDNRequest
.dn
== NULL
) {
625 return LDB_ERR_INVALID_DN_SYNTAX
;
628 msg
->r
.ModifyDNRequest
.newrdn
=
629 talloc_asprintf(msg
, "%s=%s",
630 ldb_dn_get_rdn_name(req
->op
.rename
.newdn
),
631 ldb_dn_escape_value(msg
, *ldb_dn_get_rdn_val(req
->op
.rename
.newdn
)));
632 if (msg
->r
.ModifyDNRequest
.newrdn
== NULL
) {
634 return LDB_ERR_OPERATIONS_ERROR
;
637 msg
->r
.ModifyDNRequest
.newsuperior
=
638 ldb_dn_alloc_linearized(msg
, ldb_dn_get_parent(msg
, req
->op
.rename
.newdn
));
639 if (msg
->r
.ModifyDNRequest
.newsuperior
== NULL
) {
641 return LDB_ERR_INVALID_DN_SYNTAX
;
644 msg
->r
.ModifyDNRequest
.deleteolddn
= True
;
646 return ildb_request_send(ildb
, msg
, req
);
649 static int ildb_start_trans(struct ldb_module
*module
)
651 /* TODO implement a local locking mechanism here */
656 static int ildb_end_trans(struct ldb_module
*module
)
658 /* TODO implement a local transaction mechanism here */
663 static int ildb_del_trans(struct ldb_module
*module
)
665 /* TODO implement a local locking mechanism here */
670 static int ildb_request(struct ldb_module
*module
, struct ldb_request
*req
)
672 return LDB_ERR_OPERATIONS_ERROR
;
675 static int ildb_wait(struct ldb_handle
*handle
, enum ldb_wait_type type
)
677 struct ildb_context
*ac
= talloc_get_type(handle
->private_data
, struct ildb_context
);
679 if (handle
->state
== LDB_ASYNC_DONE
) {
680 return handle
->status
;
684 return LDB_ERR_OPERATIONS_ERROR
;
687 handle
->state
= LDB_ASYNC_INIT
;
691 if (event_loop_once(ac
->req
->conn
->event
.event_ctx
) != 0) {
692 return LDB_ERR_OTHER
;
696 while (handle
->status
== LDB_SUCCESS
&& handle
->state
!= LDB_ASYNC_DONE
) {
697 if (event_loop_once(ac
->req
->conn
->event
.event_ctx
) != 0) {
698 return LDB_ERR_OTHER
;
703 return LDB_ERR_OPERATIONS_ERROR
;
706 return handle
->status
;
709 static const struct ldb_module_ops ildb_ops
= {
711 .search
= ildb_search
,
713 .modify
= ildb_modify
,
715 .rename
= ildb_rename
,
716 .request
= ildb_request
,
717 .start_transaction
= ildb_start_trans
,
718 .end_transaction
= ildb_end_trans
,
719 .del_transaction
= ildb_del_trans
,
724 connect to the database
726 static int ildb_connect(struct ldb_context
*ldb
, const char *url
,
727 unsigned int flags
, const char *options
[],
728 struct ldb_module
**_module
)
730 struct ldb_module
*module
;
731 struct ildb_private
*ildb
;
733 struct cli_credentials
*creds
;
735 module
= talloc(ldb
, struct ldb_module
);
740 talloc_set_name_const(module
, "ldb_ildap backend");
742 module
->prev
= module
->next
= NULL
;
743 module
->private_data
= NULL
;
744 module
->ops
= &ildb_ops
;
746 ildb
= talloc(module
, struct ildb_private
);
751 module
->private_data
= ildb
;
752 ildb
->module
= module
;
753 ildb
->ldap
= ldap4_new_connection(ildb
, ldb_get_opaque(ldb
, "EventContext"));
759 if (flags
& LDB_FLG_RECONNECT
) {
760 ldap_set_reconn_params(ildb
->ldap
, 10);
763 status
= ldap_connect(ildb
->ldap
, url
);
764 if (!NT_STATUS_IS_OK(status
)) {
765 ldb_debug(ldb
, LDB_DEBUG_ERROR
, "Failed to connect to ldap URL '%s' - %s\n",
766 url
, ldap_errstr(ildb
->ldap
, status
));
770 /* caller can optionally setup credentials using the opaque token 'credentials' */
771 creds
= talloc_get_type(ldb_get_opaque(ldb
, "credentials"), struct cli_credentials
);
773 struct auth_session_info
*session_info
= talloc_get_type(ldb_get_opaque(ldb
, "sessionInfo"), struct auth_session_info
);
775 creds
= session_info
->credentials
;
779 if (creds
!= NULL
&& cli_credentials_authentication_requested(creds
)) {
780 const char *bind_dn
= cli_credentials_get_bind_dn(creds
);
782 const char *password
= cli_credentials_get_password(creds
);
783 status
= ldap_bind_simple(ildb
->ldap
, bind_dn
, password
);
784 if (!NT_STATUS_IS_OK(status
)) {
785 ldb_debug(ldb
, LDB_DEBUG_ERROR
, "Failed to bind - %s\n",
786 ldap_errstr(ildb
->ldap
, status
));
790 status
= ldap_bind_sasl(ildb
->ldap
, creds
);
791 if (!NT_STATUS_IS_OK(status
)) {
792 ldb_debug(ldb
, LDB_DEBUG_ERROR
, "Failed to bind - %s\n",
793 ldap_errstr(ildb
->ldap
, status
));
807 int ldb_ildap_init(void)
809 return ldb_register_backend("ldap", ildb_connect
) +
810 ldb_register_backend("ldapi", ildb_connect
) +
811 ldb_register_backend("ldaps", ildb_connect
);