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_context
*ldb
;
60 struct ldb_module
*module
;
61 struct ldap_request
*req
;
63 int (*callback
)(struct ldb_context
*, void *, struct ldb_reply
*);
67 convert a ldb_message structure to a list of ldap_mod structures
68 ready for ildap_add() or ildap_modify()
70 static struct ldap_mod
**ildb_msg_to_mods(void *mem_ctx
, int *num_mods
,
71 const struct ldb_message
*msg
, int use_flags
)
73 struct ldap_mod
**mods
;
77 /* allocate maximum number of elements needed */
78 mods
= talloc_array(mem_ctx
, struct ldap_mod
*, msg
->num_elements
+1);
85 for (i
= 0; i
< msg
->num_elements
; i
++) {
86 const struct ldb_message_element
*el
= &msg
->elements
[i
];
88 mods
[n
] = talloc(mods
, struct ldap_mod
);
94 mods
[n
]->attrib
= *el
;
96 switch (el
->flags
& LDB_FLAG_MOD_MASK
) {
97 case LDB_FLAG_MOD_ADD
:
98 mods
[n
]->type
= LDAP_MODIFY_ADD
;
100 case LDB_FLAG_MOD_DELETE
:
101 mods
[n
]->type
= LDAP_MODIFY_DELETE
;
103 case LDB_FLAG_MOD_REPLACE
:
104 mods
[n
]->type
= LDAP_MODIFY_REPLACE
;
121 map an ildap NTSTATUS to a ldb error code
123 static int ildb_map_error(struct ildb_private
*ildb
, NTSTATUS status
)
125 if (NT_STATUS_IS_OK(status
)) {
128 ldb_set_errstring(ildb
->ldb
, ldap_errstr(ildb
->ldap
, status
));
129 if (NT_STATUS_IS_LDAP(status
)) {
130 return NT_STATUS_LDAP_CODE(status
);
132 return LDB_ERR_OPERATIONS_ERROR
;
135 static void ildb_request_timeout(struct event_context
*ev
, struct timed_event
*te
,
136 struct timeval t
, void *private_data
)
138 struct ldb_handle
*handle
= talloc_get_type(private_data
, struct ldb_handle
);
139 struct ildb_context
*ac
= talloc_get_type(handle
->private_data
, struct ildb_context
);
141 if (ac
->req
->state
== LDAP_REQUEST_PENDING
) {
142 DLIST_REMOVE(ac
->req
->conn
->pending
, ac
->req
);
145 handle
->status
= LDB_ERR_TIME_LIMIT_EXCEEDED
;
150 static void ildb_callback(struct ldap_request
*req
)
152 struct ldb_handle
*handle
= talloc_get_type(req
->async
.private_data
, struct ldb_handle
);
153 struct ildb_context
*ac
= talloc_get_type(handle
->private_data
, struct ildb_context
);
154 struct ildb_private
*ildb
= talloc_get_type(ac
->module
->private_data
, struct ildb_private
);
158 handle
->status
= LDB_SUCCESS
;
160 if (!NT_STATUS_IS_OK(req
->status
)) {
161 handle
->status
= ildb_map_error(ildb
, req
->status
);
165 if (req
->num_replies
< 1) {
166 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
172 case LDAP_TAG_ModifyRequest
:
173 if (req
->replies
[0]->type
!= LDAP_TAG_ModifyResponse
) {
174 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
177 status
= ldap_check_response(req
->conn
, &req
->replies
[0]->r
.GeneralResult
);
178 handle
->status
= ildb_map_error(ildb
, status
);
179 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
180 /* FIXME: build a corresponding ares to pass on */
181 handle
->status
= ac
->callback(ac
->module
->ldb
, ac
->context
, NULL
);
183 handle
->state
= LDB_ASYNC_DONE
;
186 case LDAP_TAG_AddRequest
:
187 if (req
->replies
[0]->type
!= LDAP_TAG_AddResponse
) {
188 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
191 status
= ldap_check_response(req
->conn
, &req
->replies
[0]->r
.GeneralResult
);
192 handle
->status
= ildb_map_error(ildb
, status
);
193 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
194 /* FIXME: build a corresponding ares to pass on */
195 handle
->status
= ac
->callback(ac
->module
->ldb
, ac
->context
, NULL
);
197 handle
->state
= LDB_ASYNC_DONE
;
200 case LDAP_TAG_DelRequest
:
201 if (req
->replies
[0]->type
!= LDAP_TAG_DelResponse
) {
202 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
205 status
= ldap_check_response(req
->conn
, &req
->replies
[0]->r
.GeneralResult
);
206 handle
->status
= ildb_map_error(ildb
, status
);
207 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
208 /* FIXME: build a corresponding ares to pass on */
209 handle
->status
= ac
->callback(ac
->module
->ldb
, ac
->context
, NULL
);
211 handle
->state
= LDB_ASYNC_DONE
;
214 case LDAP_TAG_ModifyDNRequest
:
215 if (req
->replies
[0]->type
!= LDAP_TAG_ModifyDNResponse
) {
216 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
219 status
= ldap_check_response(req
->conn
, &req
->replies
[0]->r
.GeneralResult
);
220 handle
->status
= ildb_map_error(ildb
, status
);
221 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
222 /* FIXME: build a corresponding ares to pass on */
223 handle
->status
= ac
->callback(ac
->module
->ldb
, ac
->context
, NULL
);
225 handle
->state
= LDB_ASYNC_DONE
;
228 case LDAP_TAG_SearchRequest
:
229 /* loop over all messages */
230 for (i
= 0; i
< req
->num_replies
; i
++) {
231 struct ldap_SearchResEntry
*search
;
232 struct ldb_reply
*ares
= NULL
;
233 struct ldap_message
*msg
;
236 ares
= talloc_zero(ac
, struct ldb_reply
);
238 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
242 msg
= req
->replies
[i
];
245 case LDAP_TAG_SearchResultDone
:
247 status
= ldap_check_response(req
->conn
, &msg
->r
.GeneralResult
);
248 if (!NT_STATUS_IS_OK(status
)) {
249 handle
->status
= ildb_map_error(ildb
, status
);
253 ares
->controls
= talloc_move(ares
, &msg
->controls
);
254 if (msg
->r
.SearchResultDone
.resultcode
) {
255 if (msg
->r
.SearchResultDone
.errormessage
) {
256 ldb_set_errstring(ac
->module
->ldb
, msg
->r
.SearchResultDone
.errormessage
);
260 handle
->status
= msg
->r
.SearchResultDone
.resultcode
;
261 handle
->state
= LDB_ASYNC_DONE
;
262 ares
->type
= LDB_REPLY_DONE
;
265 case LDAP_TAG_SearchResultEntry
:
268 ares
->message
= ldb_msg_new(ares
);
269 if (!ares
->message
) {
270 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
274 search
= &(msg
->r
.SearchResultEntry
);
276 ares
->message
->dn
= ldb_dn_explode_or_special(ares
->message
, search
->dn
);
277 if (ares
->message
->dn
== NULL
) {
278 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
281 ares
->message
->num_elements
= search
->num_attributes
;
282 ares
->message
->elements
= talloc_move(ares
->message
,
283 &search
->attributes
);
285 handle
->status
= LDB_SUCCESS
;
286 handle
->state
= LDB_ASYNC_PENDING
;
287 ares
->type
= LDB_REPLY_ENTRY
;
290 case LDAP_TAG_SearchResultReference
:
292 ares
->referral
= talloc_strdup(ares
, msg
->r
.SearchResultReference
.referral
);
294 handle
->status
= LDB_SUCCESS
;
295 handle
->state
= LDB_ASYNC_PENDING
;
296 ares
->type
= LDB_REPLY_REFERRAL
;
300 /* TAG not handled, fail ! */
301 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
305 ret
= ac
->callback(ac
->module
->ldb
, ac
->context
, ares
);
307 handle
->status
= ret
;
311 talloc_free(req
->replies
);
313 req
->num_replies
= 0;
318 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
323 static struct ldb_handle
*init_ildb_handle(struct ldb_module
*module
,
325 int (*callback
)(struct ldb_context
*, void *, struct ldb_reply
*))
327 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
328 struct ildb_context
*ildb_ac
;
329 struct ldb_handle
*h
;
331 h
= talloc_zero(ildb
->ldap
, struct ldb_handle
);
333 ldb_set_errstring(module
->ldb
, "Out of Memory");
339 ildb_ac
= talloc(h
, struct ildb_context
);
340 if (ildb_ac
== NULL
) {
341 ldb_set_errstring(module
->ldb
, "Out of Memory");
346 h
->private_data
= (void *)ildb_ac
;
348 h
->state
= LDB_ASYNC_INIT
;
349 h
->status
= LDB_SUCCESS
;
351 ildb_ac
->module
= module
;
352 ildb_ac
->context
= context
;
353 ildb_ac
->callback
= callback
;
358 static int ildb_request_send(struct ldb_module
*module
, struct ldap_message
*msg
,
360 int (*callback
)(struct ldb_context
*, void *, struct ldb_reply
*),
362 struct ldb_handle
**handle
)
364 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
365 struct ldb_handle
*h
= init_ildb_handle(module
, context
, callback
);
366 struct ildb_context
*ildb_ac
;
367 struct ldap_request
*req
;
370 return LDB_ERR_OPERATIONS_ERROR
;
373 ildb_ac
= talloc_get_type(h
->private_data
, struct ildb_context
);
375 req
= ldap_request_send(ildb
->ldap
, msg
);
377 ldb_set_errstring(module
->ldb
, "async send request failed");
378 return LDB_ERR_OPERATIONS_ERROR
;
382 ldb_set_errstring(module
->ldb
, "connection to remote LDAP server dropped?");
383 return LDB_ERR_OPERATIONS_ERROR
;
386 talloc_free(req
->time_event
);
387 req
->time_event
= NULL
;
389 req
->time_event
= event_add_timed(req
->conn
->event
.event_ctx
, h
,
390 timeval_current_ofs(timeout
, 0),
391 ildb_request_timeout
, h
);
394 req
->async
.fn
= ildb_callback
;
395 req
->async
.private_data
= (void *)h
;
396 ildb_ac
->req
= talloc_move(ildb_ac
, &req
);
402 static int ildb_request_noop(struct ldb_module
*module
, struct ldb_request
*req
)
404 struct ldb_handle
*h
= init_ildb_handle(module
, req
->context
, req
->callback
);
405 struct ildb_context
*ildb_ac
;
406 int ret
= LDB_SUCCESS
;
409 return LDB_ERR_OPERATIONS_ERROR
;
412 ildb_ac
= talloc_get_type(h
->private_data
, struct ildb_context
);
416 if (ildb_ac
->callback
) {
417 ret
= ildb_ac
->callback(module
->ldb
, ildb_ac
->context
, NULL
);
419 req
->handle
->state
= LDB_ASYNC_DONE
;
424 search for matching records using an asynchronous function
426 static int ildb_search(struct ldb_module
*module
, struct ldb_request
*req
)
428 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
429 struct ldap_message
*msg
;
434 if (!req
->callback
|| !req
->context
) {
435 ldb_set_errstring(module
->ldb
, "Async interface called with NULL callback function or NULL context");
436 return LDB_ERR_OPERATIONS_ERROR
;
439 if (req
->op
.search
.tree
== NULL
) {
440 ldb_set_errstring(module
->ldb
, "Invalid expression parse tree");
441 return LDB_ERR_OPERATIONS_ERROR
;
444 msg
= new_ldap_message(ildb
);
446 ldb_set_errstring(module
->ldb
, "Out of Memory");
447 return LDB_ERR_OPERATIONS_ERROR
;
450 msg
->type
= LDAP_TAG_SearchRequest
;
452 if (req
->op
.search
.base
== NULL
) {
453 msg
->r
.SearchRequest
.basedn
= talloc_strdup(msg
, "");
455 msg
->r
.SearchRequest
.basedn
= ldb_dn_linearize(msg
, req
->op
.search
.base
);
457 if (msg
->r
.SearchRequest
.basedn
== NULL
) {
458 ldb_set_errstring(module
->ldb
, "Unable to determine baseDN");
460 return LDB_ERR_OPERATIONS_ERROR
;
463 if (req
->op
.search
.scope
== LDB_SCOPE_DEFAULT
) {
464 msg
->r
.SearchRequest
.scope
= LDB_SCOPE_SUBTREE
;
466 msg
->r
.SearchRequest
.scope
= req
->op
.search
.scope
;
469 msg
->r
.SearchRequest
.deref
= LDAP_DEREFERENCE_NEVER
;
470 msg
->r
.SearchRequest
.timelimit
= 0;
471 msg
->r
.SearchRequest
.sizelimit
= 0;
472 msg
->r
.SearchRequest
.attributesonly
= 0;
473 msg
->r
.SearchRequest
.tree
= discard_const_p(struct ldb_parse_tree
, req
->op
.search
.tree
);
475 for (n
= 0; req
->op
.search
.attrs
&& req
->op
.search
.attrs
[n
]; n
++) /* noop */ ;
476 msg
->r
.SearchRequest
.num_attributes
= n
;
477 msg
->r
.SearchRequest
.attributes
= discard_const_p(char *, req
->op
.search
.attrs
),
479 msg
->controls
= req
->controls
;
481 return ildb_request_send(module
, msg
, req
->context
, req
->callback
, req
->timeout
, &(req
->handle
));
487 static int ildb_add(struct ldb_module
*module
, struct ldb_request
*req
)
489 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
490 struct ldap_message
*msg
;
491 struct ldap_mod
**mods
;
496 /* ignore ltdb specials */
497 if (ldb_dn_is_special(req
->op
.add
.message
->dn
)) {
498 return ildb_request_noop(module
, req
);
501 msg
= new_ldap_message(ildb
->ldap
);
503 return LDB_ERR_OPERATIONS_ERROR
;
506 msg
->type
= LDAP_TAG_AddRequest
;
508 msg
->r
.AddRequest
.dn
= ldb_dn_linearize(msg
, req
->op
.add
.message
->dn
);
509 if (msg
->r
.AddRequest
.dn
== NULL
) {
511 return LDB_ERR_INVALID_DN_SYNTAX
;
514 mods
= ildb_msg_to_mods(msg
, &n
, req
->op
.add
.message
, 0);
517 return LDB_ERR_OPERATIONS_ERROR
;
520 msg
->r
.AddRequest
.num_attributes
= n
;
521 msg
->r
.AddRequest
.attributes
= talloc_array(msg
, struct ldb_message_element
, n
);
522 if (msg
->r
.AddRequest
.attributes
== NULL
) {
524 return LDB_ERR_OPERATIONS_ERROR
;
527 for (i
= 0; i
< n
; i
++) {
528 msg
->r
.AddRequest
.attributes
[i
] = mods
[i
]->attrib
;
531 return ildb_request_send(module
, msg
, req
->context
, req
->callback
, req
->timeout
, &(req
->handle
));
537 static int ildb_modify(struct ldb_module
*module
, struct ldb_request
*req
)
539 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
540 struct ldap_message
*msg
;
541 struct ldap_mod
**mods
;
546 /* ignore ltdb specials */
547 if (ldb_dn_is_special(req
->op
.mod
.message
->dn
)) {
548 return ildb_request_noop(module
, req
);
551 msg
= new_ldap_message(ildb
->ldap
);
553 return LDB_ERR_OPERATIONS_ERROR
;
556 msg
->type
= LDAP_TAG_ModifyRequest
;
558 msg
->r
.ModifyRequest
.dn
= ldb_dn_linearize(msg
, req
->op
.mod
.message
->dn
);
559 if (msg
->r
.ModifyRequest
.dn
== NULL
) {
561 return LDB_ERR_INVALID_DN_SYNTAX
;
564 mods
= ildb_msg_to_mods(msg
, &n
, req
->op
.mod
.message
, 1);
567 return LDB_ERR_OPERATIONS_ERROR
;
570 msg
->r
.ModifyRequest
.num_mods
= n
;
571 msg
->r
.ModifyRequest
.mods
= talloc_array(msg
, struct ldap_mod
, n
);
572 if (msg
->r
.ModifyRequest
.mods
== NULL
) {
574 return LDB_ERR_OPERATIONS_ERROR
;
577 for (i
= 0; i
< n
; i
++) {
578 msg
->r
.ModifyRequest
.mods
[i
] = *mods
[i
];
581 return ildb_request_send(module
, msg
, req
->context
, req
->callback
, req
->timeout
, &(req
->handle
));
587 static int ildb_delete(struct ldb_module
*module
, struct ldb_request
*req
)
589 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
590 struct ldap_message
*msg
;
594 /* ignore ltdb specials */
595 if (ldb_dn_is_special(req
->op
.del
.dn
)) {
596 return ildb_request_noop(module
, req
);
599 msg
= new_ldap_message(ildb
->ldap
);
601 return LDB_ERR_OPERATIONS_ERROR
;
604 msg
->type
= LDAP_TAG_DelRequest
;
606 msg
->r
.DelRequest
.dn
= ldb_dn_linearize(msg
, req
->op
.del
.dn
);
607 if (msg
->r
.DelRequest
.dn
== NULL
) {
609 return LDB_ERR_INVALID_DN_SYNTAX
;
612 return ildb_request_send(module
, msg
, req
->context
, req
->callback
, req
->timeout
, &(req
->handle
));
618 static int ildb_rename(struct ldb_module
*module
, struct ldb_request
*req
)
620 struct ildb_private
*ildb
= talloc_get_type(module
->private_data
, struct ildb_private
);
621 struct ldap_message
*msg
;
625 /* ignore ltdb specials */
626 if (ldb_dn_is_special(req
->op
.rename
.olddn
) || ldb_dn_is_special(req
->op
.rename
.newdn
)) {
627 return ildb_request_noop(module
, req
);
630 msg
= new_ldap_message(ildb
->ldap
);
632 return LDB_ERR_OPERATIONS_ERROR
;
635 msg
->type
= LDAP_TAG_ModifyDNRequest
;
636 msg
->r
.ModifyDNRequest
.dn
= ldb_dn_linearize(msg
, req
->op
.rename
.olddn
);
637 if (msg
->r
.ModifyDNRequest
.dn
== NULL
) {
639 return LDB_ERR_INVALID_DN_SYNTAX
;
642 msg
->r
.ModifyDNRequest
.newrdn
=
643 talloc_asprintf(msg
, "%s=%s",
644 ldb_dn_get_rdn_name(req
->op
.rename
.newdn
),
645 ldb_dn_escape_value(msg
, *ldb_dn_get_rdn_val(req
->op
.rename
.newdn
)));
646 if (msg
->r
.ModifyDNRequest
.newrdn
== NULL
) {
648 return LDB_ERR_OPERATIONS_ERROR
;
651 msg
->r
.ModifyDNRequest
.newsuperior
=
652 ldb_dn_linearize(msg
,
653 ldb_dn_get_parent(msg
, req
->op
.rename
.newdn
));
654 if (msg
->r
.ModifyDNRequest
.newsuperior
== NULL
) {
656 return LDB_ERR_INVALID_DN_SYNTAX
;
659 msg
->r
.ModifyDNRequest
.deleteolddn
= True
;
661 return ildb_request_send(module
, msg
, req
->context
, req
->callback
, req
->timeout
, &(req
->handle
));
664 static int ildb_start_trans(struct ldb_module
*module
)
666 /* TODO implement a local locking mechanism here */
671 static int ildb_end_trans(struct ldb_module
*module
)
673 /* TODO implement a local transaction mechanism here */
678 static int ildb_del_trans(struct ldb_module
*module
)
680 /* TODO implement a local locking mechanism here */
685 static int ildb_request(struct ldb_module
*module
, struct ldb_request
*req
)
687 return LDB_ERR_OPERATIONS_ERROR
;
690 static int ildb_wait(struct ldb_handle
*handle
, enum ldb_wait_type type
)
692 struct ildb_context
*ac
= talloc_get_type(handle
->private_data
, struct ildb_context
);
694 if (handle
->state
== LDB_ASYNC_DONE
) {
695 return handle
->status
;
699 return LDB_ERR_OPERATIONS_ERROR
;
702 handle
->state
= LDB_ASYNC_INIT
;
706 if (event_loop_once(ac
->req
->conn
->event
.event_ctx
) != 0) {
707 return LDB_ERR_OTHER
;
711 while (handle
->status
== LDB_SUCCESS
&& handle
->state
!= LDB_ASYNC_DONE
) {
712 if (event_loop_once(ac
->req
->conn
->event
.event_ctx
) != 0) {
713 return LDB_ERR_OTHER
;
718 return LDB_ERR_OPERATIONS_ERROR
;
721 return handle
->status
;
724 static const struct ldb_module_ops ildb_ops
= {
726 .search
= ildb_search
,
728 .modify
= ildb_modify
,
730 .rename
= ildb_rename
,
731 .request
= ildb_request
,
732 .start_transaction
= ildb_start_trans
,
733 .end_transaction
= ildb_end_trans
,
734 .del_transaction
= ildb_del_trans
,
739 connect to the database
741 static int ildb_connect(struct ldb_context
*ldb
, const char *url
,
742 unsigned int flags
, const char *options
[],
743 struct ldb_module
**module
)
745 struct ildb_private
*ildb
= NULL
;
747 struct cli_credentials
*creds
;
749 ildb
= talloc(ldb
, struct ildb_private
);
757 ildb
->ldap
= ldap4_new_connection(ildb
, ldb_get_opaque(ldb
, "EventContext"));
763 if (flags
& LDB_FLG_RECONNECT
) {
764 ldap_set_reconn_params(ildb
->ldap
, 10);
767 status
= ldap_connect(ildb
->ldap
, url
);
768 if (!NT_STATUS_IS_OK(status
)) {
769 ldb_debug(ldb
, LDB_DEBUG_ERROR
, "Failed to connect to ldap URL '%s' - %s\n",
770 url
, ldap_errstr(ildb
->ldap
, status
));
775 *module
= talloc(ldb
, struct ldb_module
);
781 talloc_set_name_const(*module
, "ldb_ildap backend");
782 (*module
)->ldb
= ldb
;
783 (*module
)->prev
= (*module
)->next
= NULL
;
784 (*module
)->private_data
= ildb
;
785 (*module
)->ops
= &ildb_ops
;
787 /* caller can optionally setup credentials using the opaque token 'credentials' */
788 creds
= talloc_get_type(ldb_get_opaque(ldb
, "credentials"), struct cli_credentials
);
790 struct auth_session_info
*session_info
= talloc_get_type(ldb_get_opaque(ldb
, "sessionInfo"), struct auth_session_info
);
792 creds
= session_info
->credentials
;
796 if (creds
!= NULL
&& cli_credentials_authentication_requested(creds
)) {
797 const char *bind_dn
= cli_credentials_get_bind_dn(creds
);
799 const char *password
= cli_credentials_get_password(creds
);
800 status
= ldap_bind_simple(ildb
->ldap
, bind_dn
, password
);
801 if (!NT_STATUS_IS_OK(status
)) {
802 ldb_debug(ldb
, LDB_DEBUG_ERROR
, "Failed to bind - %s\n",
803 ldap_errstr(ildb
->ldap
, status
));
807 status
= ldap_bind_sasl(ildb
->ldap
, creds
);
808 if (!NT_STATUS_IS_OK(status
)) {
809 ldb_debug(ldb
, LDB_DEBUG_ERROR
, "Failed to bind - %s\n",
810 ldap_errstr(ildb
->ldap
, status
));
823 int ldb_ildap_init(void)
825 return ldb_register_backend("ldap", ildb_connect
) +
826 ldb_register_backend("ldapi", ildb_connect
) +
827 ldb_register_backend("ldaps", ildb_connect
);