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 asyncronous calls
42 #include "ldb/include/includes.h"
44 #define LDAP_DEPRECATED 1
52 struct ldb_module
*module
;
57 int (*callback
)(struct ldb_context
*, void *, struct ldb_reply
*);
60 static int lldb_ldap_to_ldb(int err
) {
61 /* Ldap errors and ldb errors are defined to the same values */
65 static struct ldb_handle
*init_handle(struct lldb_private
*lldb
, struct ldb_module
*module
,
67 int (*callback
)(struct ldb_context
*, void *, struct ldb_reply
*),
68 int timeout
, time_t starttime
)
70 struct lldb_context
*ac
;
73 h
= talloc_zero(lldb
, struct ldb_handle
);
75 ldb_set_errstring(module
->ldb
, "Out of Memory");
81 ac
= talloc(h
, struct lldb_context
);
83 ldb_set_errstring(module
->ldb
, "Out of Memory");
88 h
->private_data
= (void *)ac
;
90 h
->state
= LDB_ASYNC_INIT
;
91 h
->status
= LDB_SUCCESS
;
94 ac
->context
= context
;
95 ac
->callback
= callback
;
96 ac
->timeout
= timeout
;
97 ac
->starttime
= starttime
;
103 convert a ldb_message structure to a list of LDAPMod structures
104 ready for ldap_add() or ldap_modify()
106 static LDAPMod
**lldb_msg_to_mods(void *mem_ctx
, const struct ldb_message
*msg
, int use_flags
)
112 /* allocate maximum number of elements needed */
113 mods
= talloc_array(mem_ctx
, LDAPMod
*, msg
->num_elements
+1);
120 for (i
=0;i
<msg
->num_elements
;i
++) {
121 const struct ldb_message_element
*el
= &msg
->elements
[i
];
123 mods
[num_mods
] = talloc(mods
, LDAPMod
);
124 if (!mods
[num_mods
]) {
127 mods
[num_mods
+1] = NULL
;
128 mods
[num_mods
]->mod_op
= LDAP_MOD_BVALUES
;
130 switch (el
->flags
& LDB_FLAG_MOD_MASK
) {
131 case LDB_FLAG_MOD_ADD
:
132 mods
[num_mods
]->mod_op
|= LDAP_MOD_ADD
;
134 case LDB_FLAG_MOD_DELETE
:
135 mods
[num_mods
]->mod_op
|= LDAP_MOD_DELETE
;
137 case LDB_FLAG_MOD_REPLACE
:
138 mods
[num_mods
]->mod_op
|= LDAP_MOD_REPLACE
;
142 mods
[num_mods
]->mod_type
= discard_const_p(char, el
->name
);
143 mods
[num_mods
]->mod_vals
.modv_bvals
= talloc_array(mods
[num_mods
],
146 if (!mods
[num_mods
]->mod_vals
.modv_bvals
) {
150 for (j
=0;j
<el
->num_values
;j
++) {
151 mods
[num_mods
]->mod_vals
.modv_bvals
[j
] = talloc(mods
[num_mods
]->mod_vals
.modv_bvals
,
153 if (!mods
[num_mods
]->mod_vals
.modv_bvals
[j
]) {
156 mods
[num_mods
]->mod_vals
.modv_bvals
[j
]->bv_val
=
157 (char *)el
->values
[j
].data
;
158 mods
[num_mods
]->mod_vals
.modv_bvals
[j
]->bv_len
= el
->values
[j
].length
;
160 mods
[num_mods
]->mod_vals
.modv_bvals
[j
] = NULL
;
172 add a single set of ldap message values to a ldb_message
174 static int lldb_add_msg_attr(struct ldb_context
*ldb
,
175 struct ldb_message
*msg
,
176 const char *attr
, struct berval
**bval
)
179 struct ldb_message_element
*el
;
181 count
= ldap_count_values_len(bval
);
187 el
= talloc_realloc(msg
, msg
->elements
, struct ldb_message_element
,
188 msg
->num_elements
+ 1);
196 el
= &msg
->elements
[msg
->num_elements
];
198 el
->name
= talloc_strdup(msg
->elements
, attr
);
206 el
->values
= talloc_array(msg
->elements
, struct ldb_val
, count
);
212 for (i
=0;i
<count
;i
++) {
213 /* we have to ensure this is null terminated so that
214 ldb_msg_find_attr_as_string() can work */
216 (uint8_t *)talloc_size(el
->values
, bval
[i
]->bv_len
+1);
217 if (!el
->values
[i
].data
) {
221 memcpy(el
->values
[i
].data
, bval
[i
]->bv_val
, bval
[i
]->bv_len
);
222 el
->values
[i
].data
[bval
[i
]->bv_len
] = 0;
223 el
->values
[i
].length
= bval
[i
]->bv_len
;
233 search for matching records
235 static int lldb_search(struct ldb_module
*module
, struct ldb_request
*req
)
237 struct lldb_private
*lldb
= talloc_get_type(module
->private_data
, struct lldb_private
);
238 struct lldb_context
*lldb_ac
;
245 if (!req
->callback
|| !req
->context
) {
246 ldb_set_errstring(module
->ldb
, "Async interface called with NULL callback function or NULL context");
247 return LDB_ERR_OPERATIONS_ERROR
;
250 if (req
->op
.search
.tree
== NULL
) {
251 ldb_set_errstring(module
->ldb
, "Invalid expression parse tree");
252 return LDB_ERR_OPERATIONS_ERROR
;
255 if (req
->controls
!= NULL
) {
256 ldb_debug(module
->ldb
, LDB_DEBUG_WARNING
, "Controls are not yet supported by ldb_ldap backend!\n");
259 req
->handle
= init_handle(lldb
, module
, req
->context
, req
->callback
, req
->timeout
, req
->starttime
);
260 if (req
->handle
== NULL
) {
261 return LDB_ERR_OPERATIONS_ERROR
;
264 lldb_ac
= talloc_get_type(req
->handle
->private_data
, struct lldb_context
);
266 search_base
= ldb_dn_linearize(lldb_ac
, req
->op
.search
.base
);
267 if (req
->op
.search
.base
== NULL
) {
268 search_base
= talloc_strdup(lldb_ac
, "");
270 if (search_base
== NULL
) {
271 return LDB_ERR_OPERATIONS_ERROR
;
274 expression
= ldb_filter_from_tree(
276 discard_const_p(struct ldb_parse_tree
, req
->op
.search
.tree
));
277 if (expression
== NULL
) {
278 return LDB_ERR_OPERATIONS_ERROR
;
281 switch (req
->op
.search
.scope
) {
283 ldap_scope
= LDAP_SCOPE_BASE
;
285 case LDB_SCOPE_ONELEVEL
:
286 ldap_scope
= LDAP_SCOPE_ONELEVEL
;
289 ldap_scope
= LDAP_SCOPE_SUBTREE
;
293 tv
.tv_sec
= req
->timeout
;
296 ret
= ldap_search_ext(lldb
->ldap
, search_base
, ldap_scope
,
298 discard_const_p(char *, req
->op
.search
.attrs
),
306 if (ret
!= LDAP_SUCCESS
) {
307 ldb_set_errstring(module
->ldb
, ldap_err2string(ret
));
310 return lldb_ldap_to_ldb(ret
);
316 static int lldb_add(struct ldb_module
*module
, struct ldb_request
*req
)
318 struct lldb_private
*lldb
= talloc_get_type(module
->private_data
, struct lldb_private
);
319 struct lldb_context
*lldb_ac
;
324 /* ltdb specials should not reach this point */
325 if (ldb_dn_is_special(req
->op
.add
.message
->dn
)) {
326 return LDB_ERR_INVALID_DN_SYNTAX
;
329 req
->handle
= init_handle(lldb
, module
, req
->context
, req
->callback
, req
->timeout
, req
->starttime
);
330 if (req
->handle
== NULL
) {
331 return LDB_ERR_OPERATIONS_ERROR
;
334 lldb_ac
= talloc_get_type(req
->handle
->private_data
, struct lldb_context
);
336 mods
= lldb_msg_to_mods(lldb_ac
, req
->op
.add
.message
, 0);
338 return LDB_ERR_OPERATIONS_ERROR
;
341 dn
= ldb_dn_linearize(lldb_ac
, req
->op
.add
.message
->dn
);
343 return LDB_ERR_OPERATIONS_ERROR
;
346 ret
= ldap_add_ext(lldb
->ldap
, dn
, mods
,
351 if (ret
!= LDAP_SUCCESS
) {
352 ldb_set_errstring(module
->ldb
, ldap_err2string(ret
));
355 return lldb_ldap_to_ldb(ret
);
361 static int lldb_modify(struct ldb_module
*module
, struct ldb_request
*req
)
363 struct lldb_private
*lldb
= talloc_get_type(module
->private_data
, struct lldb_private
);
364 struct lldb_context
*lldb_ac
;
369 /* ltdb specials should not reach this point */
370 if (ldb_dn_is_special(req
->op
.mod
.message
->dn
)) {
371 return LDB_ERR_INVALID_DN_SYNTAX
;
374 req
->handle
= init_handle(lldb
, module
, req
->context
, req
->callback
, req
->timeout
, req
->starttime
);
375 if (req
->handle
== NULL
) {
376 return LDB_ERR_OPERATIONS_ERROR
;
379 lldb_ac
= talloc_get_type(req
->handle
->private_data
, struct lldb_context
);
381 mods
= lldb_msg_to_mods(lldb_ac
, req
->op
.mod
.message
, 1);
383 return LDB_ERR_OPERATIONS_ERROR
;
386 dn
= ldb_dn_linearize(lldb_ac
, req
->op
.mod
.message
->dn
);
388 return LDB_ERR_OPERATIONS_ERROR
;
391 ret
= ldap_modify_ext(lldb
->ldap
, dn
, mods
,
396 if (ret
!= LDAP_SUCCESS
) {
397 ldb_set_errstring(module
->ldb
, ldap_err2string(ret
));
400 return lldb_ldap_to_ldb(ret
);
406 static int lldb_delete(struct ldb_module
*module
, struct ldb_request
*req
)
408 struct lldb_private
*lldb
= talloc_get_type(module
->private_data
, struct lldb_private
);
409 struct lldb_context
*lldb_ac
;
413 /* ltdb specials should not reach this point */
414 if (ldb_dn_is_special(req
->op
.del
.dn
)) {
415 return LDB_ERR_INVALID_DN_SYNTAX
;
418 req
->handle
= init_handle(lldb
, module
, req
->context
, req
->callback
, req
->timeout
, req
->starttime
);
419 if (req
->handle
== NULL
) {
420 return LDB_ERR_OPERATIONS_ERROR
;
423 lldb_ac
= talloc_get_type(req
->handle
->private_data
, struct lldb_context
);
425 dnstr
= ldb_dn_linearize(lldb_ac
, req
->op
.del
.dn
);
427 ret
= ldap_delete_ext(lldb
->ldap
, dnstr
,
432 if (ret
!= LDAP_SUCCESS
) {
433 ldb_set_errstring(module
->ldb
, ldap_err2string(ret
));
436 return lldb_ldap_to_ldb(ret
);
442 static int lldb_rename(struct ldb_module
*module
, struct ldb_request
*req
)
444 struct lldb_private
*lldb
= talloc_get_type(module
->private_data
, struct lldb_private
);
445 struct lldb_context
*lldb_ac
;
451 /* ltdb specials should not reach this point */
452 if (ldb_dn_is_special(req
->op
.rename
.olddn
) || ldb_dn_is_special(req
->op
.rename
.newdn
)) {
453 return LDB_ERR_INVALID_DN_SYNTAX
;
456 req
->handle
= init_handle(lldb
, module
, req
->context
, req
->callback
, req
->timeout
, req
->starttime
);
457 if (req
->handle
== NULL
) {
458 return LDB_ERR_OPERATIONS_ERROR
;
461 lldb_ac
= talloc_get_type(req
->handle
->private_data
, struct lldb_context
);
463 old_dn
= ldb_dn_linearize(lldb_ac
, req
->op
.rename
.olddn
);
464 if (old_dn
== NULL
) {
465 return LDB_ERR_OPERATIONS_ERROR
;
468 newrdn
= talloc_asprintf(lldb_ac
, "%s=%s",
469 ldb_dn_get_rdn_name(req
->op
.rename
.newdn
),
470 ldb_dn_escape_value(lldb
, *(ldb_dn_get_rdn_val(req
->op
.rename
.newdn
))));
472 return LDB_ERR_OPERATIONS_ERROR
;
475 parentdn
= ldb_dn_linearize(lldb_ac
, ldb_dn_get_parent(lldb_ac
, req
->op
.rename
.newdn
));
477 return LDB_ERR_OPERATIONS_ERROR
;
480 ret
= ldap_rename(lldb
->ldap
, old_dn
, newrdn
, parentdn
,
484 if (ret
!= LDAP_SUCCESS
) {
485 ldb_set_errstring(module
->ldb
, ldap_err2string(ret
));
488 return lldb_ldap_to_ldb(ret
);
491 static int lldb_parse_result(struct ldb_handle
*handle
, LDAPMessage
*result
)
493 struct lldb_context
*ac
= talloc_get_type(handle
->private_data
, struct lldb_context
);
494 struct lldb_private
*lldb
= talloc_get_type(ac
->module
->private_data
, struct lldb_private
);
495 struct ldb_reply
*ares
= NULL
;
498 char *matcheddnp
= NULL
;
499 char *errmsgp
= NULL
;
500 char **referralsp
= NULL
;
501 LDAPControl
**serverctrlsp
= NULL
;
502 int ret
= LDB_SUCCESS
;
504 type
= ldap_msgtype(result
);
510 case LDAP_RES_SEARCH_ENTRY
:
511 msg
= ldap_first_entry(lldb
->ldap
, result
);
513 BerElement
*berptr
= NULL
;
516 ares
= talloc_zero(ac
, struct ldb_reply
);
518 ret
= LDB_ERR_OPERATIONS_ERROR
;
522 ares
->message
= ldb_msg_new(ares
);
523 if (!ares
->message
) {
524 ret
= LDB_ERR_OPERATIONS_ERROR
;
528 dn
= ldap_get_dn(lldb
->ldap
, msg
);
530 ret
= LDB_ERR_OPERATIONS_ERROR
;
533 ares
->message
->dn
= ldb_dn_explode_or_special(ares
->message
, dn
);
534 if (ares
->message
->dn
== NULL
) {
535 ret
= LDB_ERR_OPERATIONS_ERROR
;
540 ares
->message
->num_elements
= 0;
541 ares
->message
->elements
= NULL
;
542 ares
->message
->private_data
= NULL
;
544 /* loop over all attributes */
545 for (attr
=ldap_first_attribute(lldb
->ldap
, msg
, &berptr
);
547 attr
=ldap_next_attribute(lldb
->ldap
, msg
, berptr
)) {
548 struct berval
**bval
;
549 bval
= ldap_get_values_len(lldb
->ldap
, msg
, attr
);
552 lldb_add_msg_attr(ac
->module
->ldb
, ares
->message
, attr
, bval
);
553 ldap_value_free_len(bval
);
556 if (berptr
) ber_free(berptr
, 0);
559 ares
->type
= LDB_REPLY_ENTRY
;
560 ret
= ac
->callback(ac
->module
->ldb
, ac
->context
, ares
);
562 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
563 handle
->state
= LDB_ASYNC_DONE
;
567 case LDAP_RES_SEARCH_REFERENCE
:
568 if (ldap_parse_result(lldb
->ldap
, result
, &handle
->status
,
569 &matcheddnp
, &errmsgp
,
570 &referralsp
, &serverctrlsp
, 0) != LDAP_SUCCESS
) {
571 ret
= LDB_ERR_OPERATIONS_ERROR
;
574 if (referralsp
== NULL
) {
575 handle
->status
= LDB_ERR_PROTOCOL_ERROR
;
579 ares
= talloc_zero(ac
, struct ldb_reply
);
581 ret
= LDB_ERR_OPERATIONS_ERROR
;
585 ares
->referral
= talloc_strdup(ares
, *referralsp
);
586 ares
->type
= LDB_REPLY_REFERRAL
;
587 ret
= ac
->callback(ac
->module
->ldb
, ac
->context
, ares
);
591 case LDAP_RES_SEARCH_RESULT
:
592 if (ldap_parse_result(lldb
->ldap
, result
, &handle
->status
,
593 &matcheddnp
, &errmsgp
,
594 &referralsp
, &serverctrlsp
, 0) != LDAP_SUCCESS
) {
595 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
599 ares
= talloc_zero(ac
, struct ldb_reply
);
601 ret
= LDB_ERR_OPERATIONS_ERROR
;
605 if (serverctrlsp
!= NULL
) {
606 /* FIXME: transform the LDAPControl list into an ldb_control one */
607 ares
->controls
= NULL
;
610 ares
->type
= LDB_REPLY_DONE
;
611 handle
->state
= LDB_ASYNC_DONE
;
612 ret
= ac
->callback(ac
->module
->ldb
, ac
->context
, ares
);
616 case LDAP_RES_MODIFY
:
618 case LDAP_RES_DELETE
:
620 if (ldap_parse_result(lldb
->ldap
, result
, &handle
->status
,
621 &matcheddnp
, &errmsgp
,
622 &referralsp
, &serverctrlsp
, 0) != LDAP_SUCCESS
) {
623 handle
->status
= LDB_ERR_OPERATIONS_ERROR
;
626 if (ac
->callback
&& handle
->status
== LDB_SUCCESS
) {
627 ares
= NULL
; /* FIXME: build a corresponding ares to pass on */
628 ret
= ac
->callback(ac
->module
->ldb
, ac
->context
, ares
);
630 handle
->state
= LDB_ASYNC_DONE
;
634 ret
= LDB_ERR_PROTOCOL_ERROR
;
638 if (matcheddnp
) ldap_memfree(matcheddnp
);
639 if (errmsgp
&& *errmsgp
) {
640 ldb_set_errstring(ac
->module
->ldb
, errmsgp
);
641 } else if (handle
->status
) {
642 ldb_set_errstring(ac
->module
->ldb
, ldap_err2string(handle
->status
));
645 ldap_memfree(errmsgp
);
647 if (referralsp
) ldap_value_free(referralsp
);
648 if (serverctrlsp
) ldap_controls_free(serverctrlsp
);
650 ldap_msgfree(result
);
651 return lldb_ldap_to_ldb(handle
->status
);
654 handle
->state
= LDB_ASYNC_DONE
;
655 ldap_msgfree(result
);
659 static int lldb_wait(struct ldb_handle
*handle
, enum ldb_wait_type type
)
661 struct lldb_context
*ac
= talloc_get_type(handle
->private_data
, struct lldb_context
);
662 struct lldb_private
*lldb
= talloc_get_type(handle
->module
->private_data
, struct lldb_private
);
663 struct timeval timeout
;
667 if (handle
->state
== LDB_ASYNC_DONE
) {
668 return handle
->status
;
671 if (!ac
|| !ac
->msgid
) {
672 return LDB_ERR_OPERATIONS_ERROR
;
675 handle
->state
= LDB_ASYNC_PENDING
;
676 handle
->status
= LDB_SUCCESS
;
681 if ((ac
->timeout
!= -1) &&
682 ((ac
->starttime
+ ac
->timeout
) > time(NULL
))) {
683 return LDB_ERR_TIME_LIMIT_EXCEEDED
;
689 lret
= ldap_result(lldb
->ldap
, ac
->msgid
, 0, &timeout
, &result
);
691 return LDB_ERR_OPERATIONS_ERROR
;
698 return lldb_parse_result(handle
, result
);
702 ret
= LDB_ERR_OPERATIONS_ERROR
;
704 while (handle
->status
== LDB_SUCCESS
&& handle
->state
!= LDB_ASYNC_DONE
) {
706 if (ac
->timeout
== -1) {
707 lret
= ldap_result(lldb
->ldap
, ac
->msgid
, 0, NULL
, &result
);
709 timeout
.tv_sec
= ac
->timeout
- (time(NULL
) - ac
->starttime
);
710 if (timeout
.tv_sec
<= 0)
711 return LDB_ERR_TIME_LIMIT_EXCEEDED
;
712 lret
= ldap_result(lldb
->ldap
, ac
->msgid
, 0, &timeout
, &result
);
715 return LDB_ERR_OPERATIONS_ERROR
;
718 return LDB_ERR_TIME_LIMIT_EXCEEDED
;
721 ret
= lldb_parse_result(handle
, result
);
722 if (ret
!= LDB_SUCCESS
) {
730 handle
->state
= LDB_ASYNC_DONE
;
731 ret
= LDB_ERR_OPERATIONS_ERROR
;
738 static int lldb_start_trans(struct ldb_module
*module
)
740 /* TODO implement a local transaction mechanism here */
745 static int lldb_end_trans(struct ldb_module
*module
)
747 /* TODO implement a local transaction mechanism here */
752 static int lldb_del_trans(struct ldb_module
*module
)
754 /* TODO implement a local transaction mechanism here */
759 static int lldb_request(struct ldb_module
*module
, struct ldb_request
*req
)
761 return LDB_ERR_OPERATIONS_ERROR
;
764 static const struct ldb_module_ops lldb_ops
= {
766 .search
= lldb_search
,
768 .modify
= lldb_modify
,
770 .rename
= lldb_rename
,
771 .request
= lldb_request
,
772 .start_transaction
= lldb_start_trans
,
773 .end_transaction
= lldb_end_trans
,
774 .del_transaction
= lldb_del_trans
,
779 static int lldb_destructor(struct lldb_private
*lldb
)
781 ldap_unbind(lldb
->ldap
);
786 connect to the database
788 static int lldb_connect(struct ldb_context
*ldb
,
791 const char *options
[],
792 struct ldb_module
**module
)
794 struct lldb_private
*lldb
= NULL
;
798 lldb
= talloc(ldb
, struct lldb_private
);
806 ret
= ldap_initialize(&lldb
->ldap
, url
);
807 if (ret
!= LDAP_SUCCESS
) {
808 ldb_debug(ldb
, LDB_DEBUG_FATAL
, "ldap_initialize failed for URL '%s' - %s\n",
809 url
, ldap_err2string(ret
));
813 talloc_set_destructor(lldb
, lldb_destructor
);
815 ret
= ldap_set_option(lldb
->ldap
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
816 if (ret
!= LDAP_SUCCESS
) {
817 ldb_debug(ldb
, LDB_DEBUG_FATAL
, "ldap_set_option failed - %s\n",
818 ldap_err2string(ret
));
822 *module
= talloc(ldb
, struct ldb_module
);
823 if (*module
== NULL
) {
828 talloc_set_name_const(*module
, "ldb_ldap backend");
829 (*module
)->ldb
= ldb
;
830 (*module
)->prev
= (*module
)->next
= NULL
;
831 (*module
)->private_data
= lldb
;
832 (*module
)->ops
= &lldb_ops
;
841 int ldb_ldap_init(void)
843 return ldb_register_backend("ldap", lldb_connect
) +
844 ldb_register_backend("ldapi", lldb_connect
) +
845 ldb_register_backend("ldaps", lldb_connect
);