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
41 #include "ldb_includes.h"
42 #include "ldb_module.h"
44 #define LDAP_DEPRECATED 1
52 struct ldb_module
*module
;
53 struct ldb_request
*req
;
55 struct lldb_private
*lldb
;
57 struct ldb_control
**controls
;
61 static int lldb_ldap_to_ldb(int err
) {
62 /* Ldap errors and ldb errors are defined to the same values */
67 convert a ldb_message structure to a list of LDAPMod structures
68 ready for ldap_add() or ldap_modify()
70 static LDAPMod
**lldb_msg_to_mods(void *mem_ctx
, const struct ldb_message
*msg
, int use_flags
)
76 /* allocate maximum number of elements needed */
77 mods
= talloc_array(mem_ctx
, LDAPMod
*, msg
->num_elements
+1);
84 for (i
=0;i
<msg
->num_elements
;i
++) {
85 const struct ldb_message_element
*el
= &msg
->elements
[i
];
87 mods
[num_mods
] = talloc(mods
, LDAPMod
);
88 if (!mods
[num_mods
]) {
91 mods
[num_mods
+1] = NULL
;
92 mods
[num_mods
]->mod_op
= LDAP_MOD_BVALUES
;
94 switch (el
->flags
& LDB_FLAG_MOD_MASK
) {
95 case LDB_FLAG_MOD_ADD
:
96 mods
[num_mods
]->mod_op
|= LDAP_MOD_ADD
;
98 case LDB_FLAG_MOD_DELETE
:
99 mods
[num_mods
]->mod_op
|= LDAP_MOD_DELETE
;
101 case LDB_FLAG_MOD_REPLACE
:
102 mods
[num_mods
]->mod_op
|= LDAP_MOD_REPLACE
;
106 mods
[num_mods
]->mod_type
= discard_const_p(char, el
->name
);
107 mods
[num_mods
]->mod_vals
.modv_bvals
= talloc_array(mods
[num_mods
],
110 if (!mods
[num_mods
]->mod_vals
.modv_bvals
) {
114 for (j
=0;j
<el
->num_values
;j
++) {
115 mods
[num_mods
]->mod_vals
.modv_bvals
[j
] = talloc(mods
[num_mods
]->mod_vals
.modv_bvals
,
117 if (!mods
[num_mods
]->mod_vals
.modv_bvals
[j
]) {
120 mods
[num_mods
]->mod_vals
.modv_bvals
[j
]->bv_val
= el
->values
[j
].data
;
121 mods
[num_mods
]->mod_vals
.modv_bvals
[j
]->bv_len
= el
->values
[j
].length
;
123 mods
[num_mods
]->mod_vals
.modv_bvals
[j
] = NULL
;
135 add a single set of ldap message values to a ldb_message
137 static int lldb_add_msg_attr(struct ldb_context
*ldb
,
138 struct ldb_message
*msg
,
139 const char *attr
, struct berval
**bval
)
142 struct ldb_message_element
*el
;
144 count
= ldap_count_values_len(bval
);
150 el
= talloc_realloc(msg
, msg
->elements
, struct ldb_message_element
,
151 msg
->num_elements
+ 1);
159 el
= &msg
->elements
[msg
->num_elements
];
161 el
->name
= talloc_strdup(msg
->elements
, attr
);
169 el
->values
= talloc_array(msg
->elements
, struct ldb_val
, count
);
175 for (i
=0;i
<count
;i
++) {
176 /* we have to ensure this is null terminated so that
177 ldb_msg_find_attr_as_string() can work */
178 el
->values
[i
].data
= talloc_size(el
->values
, bval
[i
]->bv_len
+1);
179 if (!el
->values
[i
].data
) {
183 memcpy(el
->values
[i
].data
, bval
[i
]->bv_val
, bval
[i
]->bv_len
);
184 el
->values
[i
].data
[bval
[i
]->bv_len
] = 0;
185 el
->values
[i
].length
= bval
[i
]->bv_len
;
195 search for matching records
197 static int lldb_search(struct lldb_context
*lldb_ac
)
199 struct ldb_context
*ldb
;
200 struct lldb_private
*lldb
= lldb_ac
->lldb
;
201 struct ldb_module
*module
= lldb_ac
->module
;
202 struct ldb_request
*req
= lldb_ac
->req
;
209 ldb
= ldb_module_get_ctx(module
);
211 if (!req
->callback
|| !req
->context
) {
212 ldb_set_errstring(ldb
, "Async interface called with NULL callback function or NULL context");
213 return LDB_ERR_OPERATIONS_ERROR
;
216 if (req
->op
.search
.tree
== NULL
) {
217 ldb_set_errstring(ldb
, "Invalid expression parse tree");
218 return LDB_ERR_OPERATIONS_ERROR
;
221 if (req
->controls
!= NULL
) {
222 ldb_debug(ldb
, LDB_DEBUG_WARNING
, "Controls are not yet supported by ldb_ldap backend!");
225 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
227 search_base
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.search
.base
);
228 if (req
->op
.search
.base
== NULL
) {
229 search_base
= talloc_strdup(lldb_ac
, "");
231 if (search_base
== NULL
) {
232 return LDB_ERR_OPERATIONS_ERROR
;
235 expression
= ldb_filter_from_tree(lldb_ac
, req
->op
.search
.tree
);
236 if (expression
== NULL
) {
237 return LDB_ERR_OPERATIONS_ERROR
;
240 switch (req
->op
.search
.scope
) {
242 ldap_scope
= LDAP_SCOPE_BASE
;
244 case LDB_SCOPE_ONELEVEL
:
245 ldap_scope
= LDAP_SCOPE_ONELEVEL
;
248 ldap_scope
= LDAP_SCOPE_SUBTREE
;
252 tv
.tv_sec
= req
->timeout
;
255 ret
= ldap_search_ext(lldb
->ldap
, search_base
, ldap_scope
,
257 discard_const_p(char *, req
->op
.search
.attrs
),
265 if (ret
!= LDAP_SUCCESS
) {
266 ldb_set_errstring(ldb
, ldap_err2string(ret
));
269 return lldb_ldap_to_ldb(ret
);
275 static int lldb_add(struct lldb_context
*lldb_ac
)
277 struct ldb_context
*ldb
;
278 struct lldb_private
*lldb
= lldb_ac
->lldb
;
279 struct ldb_module
*module
= lldb_ac
->module
;
280 struct ldb_request
*req
= lldb_ac
->req
;
285 ldb_module_get_ctx(module
);
287 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
289 mods
= lldb_msg_to_mods(lldb_ac
, req
->op
.add
.message
, 0);
291 return LDB_ERR_OPERATIONS_ERROR
;
294 dn
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.add
.message
->dn
);
296 return LDB_ERR_OPERATIONS_ERROR
;
299 ret
= ldap_add_ext(lldb
->ldap
, dn
, mods
,
304 if (ret
!= LDAP_SUCCESS
) {
305 ldb_set_errstring(ldb
, ldap_err2string(ret
));
308 return lldb_ldap_to_ldb(ret
);
314 static int lldb_modify(struct lldb_context
*lldb_ac
)
316 struct ldb_context
*ldb
;
317 struct lldb_private
*lldb
= lldb_ac
->lldb
;
318 struct ldb_module
*module
= lldb_ac
->module
;
319 struct ldb_request
*req
= lldb_ac
->req
;
324 ldb_module_get_ctx(module
);
326 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
328 mods
= lldb_msg_to_mods(lldb_ac
, req
->op
.mod
.message
, 1);
330 return LDB_ERR_OPERATIONS_ERROR
;
333 dn
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.mod
.message
->dn
);
335 return LDB_ERR_OPERATIONS_ERROR
;
338 ret
= ldap_modify_ext(lldb
->ldap
, dn
, mods
,
343 if (ret
!= LDAP_SUCCESS
) {
344 ldb_set_errstring(ldb
, ldap_err2string(ret
));
347 return lldb_ldap_to_ldb(ret
);
353 static int lldb_delete(struct lldb_context
*lldb_ac
)
355 struct ldb_context
*ldb
;
356 struct lldb_private
*lldb
= lldb_ac
->lldb
;
357 struct ldb_module
*module
= lldb_ac
->module
;
358 struct ldb_request
*req
= lldb_ac
->req
;
362 ldb_module_get_ctx(module
);
364 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
366 dnstr
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.del
.dn
);
368 ret
= ldap_delete_ext(lldb
->ldap
, dnstr
,
373 if (ret
!= LDAP_SUCCESS
) {
374 ldb_set_errstring(ldb
, ldap_err2string(ret
));
377 return lldb_ldap_to_ldb(ret
);
383 static int lldb_rename(struct lldb_context
*lldb_ac
)
385 struct ldb_context
*ldb
;
386 struct lldb_private
*lldb
= lldb_ac
->lldb
;
387 struct ldb_module
*module
= lldb_ac
->module
;
388 struct ldb_request
*req
= lldb_ac
->req
;
394 ldb_module_get_ctx(module
);
396 ldb_request_set_state(req
, LDB_ASYNC_PENDING
);
398 old_dn
= ldb_dn_alloc_linearized(lldb_ac
, req
->op
.rename
.olddn
);
399 if (old_dn
== NULL
) {
400 return LDB_ERR_OPERATIONS_ERROR
;
403 newrdn
= talloc_asprintf(lldb_ac
, "%s=%s",
404 ldb_dn_get_rdn_name(req
->op
.rename
.newdn
),
405 ldb_dn_escape_value(lldb
, *(ldb_dn_get_rdn_val(req
->op
.rename
.newdn
))));
407 return LDB_ERR_OPERATIONS_ERROR
;
410 parentdn
= ldb_dn_alloc_linearized(lldb_ac
, ldb_dn_get_parent(lldb_ac
, req
->op
.rename
.newdn
));
412 return LDB_ERR_OPERATIONS_ERROR
;
415 ret
= ldap_rename(lldb
->ldap
, old_dn
, newrdn
, parentdn
,
419 if (ret
!= LDAP_SUCCESS
) {
420 ldb_set_errstring(ldb
, ldap_err2string(ret
));
423 return lldb_ldap_to_ldb(ret
);
426 static int lldb_start_trans(struct ldb_module
*module
)
428 /* TODO implement a local transaction mechanism here */
433 static int lldb_end_trans(struct ldb_module
*module
)
435 /* TODO implement a local transaction mechanism here */
440 static int lldb_del_trans(struct ldb_module
*module
)
442 /* TODO implement a local transaction mechanism here */
447 void lldb_request_done(struct lldb_context
*ac
,
448 struct ldb_control
**ctrls
, int error
)
450 struct ldb_request
*req
;
451 struct ldb_reply
*ares
;
455 ares
= talloc_zero(req
, struct ldb_reply
);
457 ldb_oom(ldb_module_get_ctx(ac
->module
));
458 req
->callback(req
, NULL
);
461 ares
->type
= LDB_REPLY_DONE
;
462 ares
->controls
= talloc_steal(ares
, ctrls
);
465 req
->callback(req
, ares
);
468 /* return false if the request is still in progress
469 * return true if the request is completed
471 static bool lldb_parse_result(struct lldb_context
*ac
, LDAPMessage
*result
)
473 struct ldb_context
*ldb
;
474 struct lldb_private
*lldb
= ac
->lldb
;
475 LDAPControl
**serverctrlsp
= NULL
;
476 char **referralsp
= NULL
;
477 char *matcheddnp
= NULL
;
478 char *errmsgp
= NULL
;
481 struct ldb_message
*ldbmsg
;
483 bool callback_failed
;
489 ldb
= ldb_module_get_ctx(ac
->module
);
491 type
= ldap_msgtype(result
);
492 callback_failed
= false;
493 request_done
= false;
496 case LDAP_RES_SEARCH_ENTRY
:
498 msg
= ldap_first_entry(lldb
->ldap
, result
);
500 BerElement
*berptr
= NULL
;
503 ldbmsg
= ldb_msg_new(ac
);
505 ret
= LDB_ERR_OPERATIONS_ERROR
;
509 dn
= ldap_get_dn(lldb
->ldap
, msg
);
512 ret
= LDB_ERR_OPERATIONS_ERROR
;
515 ldbmsg
->dn
= ldb_dn_new(ldbmsg
, ldb
, dn
);
516 if ( ! ldb_dn_validate(ldbmsg
->dn
)) {
518 ret
= LDB_ERR_OPERATIONS_ERROR
;
523 ldbmsg
->num_elements
= 0;
524 ldbmsg
->elements
= NULL
;
526 /* loop over all attributes */
527 for (attr
=ldap_first_attribute(lldb
->ldap
, msg
, &berptr
);
529 attr
=ldap_next_attribute(lldb
->ldap
, msg
, berptr
)) {
530 struct berval
**bval
;
531 bval
= ldap_get_values_len(lldb
->ldap
, msg
, attr
);
534 lldb_add_msg_attr(ldb
, ldbmsg
, attr
, bval
);
535 ldap_value_free_len(bval
);
538 if (berptr
) ber_free(berptr
, 0);
540 ret
= ldb_module_send_entry(ac
->req
, ldbmsg
, NULL
/* controls not yet supported */);
541 if (ret
!= LDB_SUCCESS
) {
543 callback_failed
= true;
546 ret
= LDB_ERR_OPERATIONS_ERROR
;
550 case LDAP_RES_SEARCH_REFERENCE
:
552 if (ldap_parse_result(lldb
->ldap
, result
, &ret
,
553 &matcheddnp
, &errmsgp
,
554 &referralsp
, &serverctrlsp
, 0) != LDAP_SUCCESS
) {
555 ret
= LDB_ERR_OPERATIONS_ERROR
;
557 if (ret
!= LDB_SUCCESS
) {
560 if (referralsp
== NULL
) {
561 ret
= LDB_ERR_PROTOCOL_ERROR
;
565 for (i
= 0; referralsp
[i
]; i
++) {
566 referral
= talloc_strdup(ac
, referralsp
[i
]);
568 ret
= ldb_module_send_referral(ac
->req
, referral
);
569 if (ret
!= LDB_SUCCESS
) {
570 callback_failed
= true;
576 case LDAP_RES_SEARCH_RESULT
:
577 case LDAP_RES_MODIFY
:
579 case LDAP_RES_DELETE
:
582 if (ldap_parse_result(lldb
->ldap
, result
, &ret
,
583 &matcheddnp
, &errmsgp
,
584 &referralsp
, &serverctrlsp
, 0) != LDAP_SUCCESS
) {
585 ret
= LDB_ERR_OPERATIONS_ERROR
;
587 if (ret
!= LDB_SUCCESS
) {
591 if (serverctrlsp
!= NULL
) {
592 /* FIXME: transform the LDAPControl list into an ldb_control one */
600 ret
= LDB_ERR_PROTOCOL_ERROR
;
604 if (ret
!= LDB_SUCCESS
) {
606 /* if the callback failed the caller will have freed the
607 * request. Just return and don't try to use it */
608 if (callback_failed
) {
610 /* tell lldb_wait to remove the request from the
613 goto free_and_return
;
620 lldb_request_done(ac
, ac
->controls
, ret
);
622 goto free_and_return
;
629 if (matcheddnp
) ldap_memfree(matcheddnp
);
630 if (errmsgp
&& *errmsgp
) {
631 ldb_set_errstring(ldb
, errmsgp
);
634 ldap_memfree(errmsgp
);
636 if (referralsp
) ldap_value_free(referralsp
);
637 if (serverctrlsp
) ldap_controls_free(serverctrlsp
);
639 ldap_msgfree(result
);
644 static void lldb_timeout(struct tevent_context
*ev
,
645 struct tevent_timer
*te
,
649 struct lldb_context
*ac
;
650 ac
= talloc_get_type(private_data
, struct lldb_context
);
652 lldb_request_done(ac
, NULL
, LDB_ERR_TIME_LIMIT_EXCEEDED
);
655 static void lldb_callback(struct tevent_context
*ev
,
656 struct tevent_timer
*te
,
660 struct lldb_context
*ac
;
661 struct tevent_timer
*lte
;
666 ac
= talloc_get_type(private_data
, struct lldb_context
);
669 lldb_request_done(ac
, NULL
, LDB_ERR_OPERATIONS_ERROR
);
675 lret
= ldap_result(ac
->lldb
->ldap
, ac
->msgid
, 0, &tv
, &result
);
680 lldb_request_done(ac
, NULL
, LDB_ERR_OPERATIONS_ERROR
);
684 if ( ! lldb_parse_result(ac
, result
)) {
693 lte
= tevent_add_timer(ev
, ac
, tv
, lldb_callback
, ac
);
695 lldb_request_done(ac
, NULL
, LDB_ERR_OPERATIONS_ERROR
);
699 static bool lldb_dn_is_special(struct ldb_request
*req
)
701 struct ldb_dn
*dn
= NULL
;
703 switch (req
->operation
) {
705 dn
= req
->op
.add
.message
->dn
;
708 dn
= req
->op
.mod
.message
->dn
;
714 dn
= req
->op
.rename
.olddn
;
720 if (dn
&& ldb_dn_is_special(dn
)) {
726 static void lldb_auto_done_callback(struct tevent_context
*ev
,
727 struct tevent_timer
*te
,
731 struct lldb_context
*ac
;
733 ac
= talloc_get_type(private_data
, struct lldb_context
);
734 lldb_request_done(ac
, NULL
, LDB_SUCCESS
);
737 static int lldb_handle_request(struct ldb_module
*module
, struct ldb_request
*req
)
739 struct ldb_context
*ldb
;
740 struct lldb_private
*lldb
;
741 struct lldb_context
*ac
;
742 struct tevent_context
*ev
;
743 struct tevent_timer
*te
;
747 lldb
= talloc_get_type(ldb_module_get_private(module
), struct lldb_private
);
748 ldb
= ldb_module_get_ctx(module
);
750 if (req
->starttime
== 0 || req
->timeout
== 0) {
751 ldb_set_errstring(ldb
, "Invalid timeout settings");
752 return LDB_ERR_TIME_LIMIT_EXCEEDED
;
755 ev
= ldb_get_event_context(ldb
);
757 return LDB_ERR_OPERATIONS_ERROR
;
760 ac
= talloc_zero(ldb
, struct lldb_context
);
762 ldb_set_errstring(ldb
, "Out of Memory");
763 return LDB_ERR_OPERATIONS_ERROR
;
771 if (lldb_dn_is_special(req
)) {
774 te
= tevent_add_timer(ev
, ac
, tv
,
775 lldb_auto_done_callback
, ac
);
777 return LDB_ERR_OPERATIONS_ERROR
;
783 switch (ac
->req
->operation
) {
785 ret
= lldb_search(ac
);
791 ret
= lldb_modify(ac
);
794 ret
= lldb_delete(ac
);
797 ret
= lldb_rename(ac
);
800 /* no other op supported */
801 ret
= LDB_ERR_OPERATIONS_ERROR
;
805 if (ret
!= LDB_SUCCESS
) {
806 lldb_request_done(ac
, NULL
, ret
);
812 te
= tevent_add_timer(ev
, ac
, tv
, lldb_callback
, ac
);
814 return LDB_ERR_OPERATIONS_ERROR
;
818 tv
.tv_sec
= req
->starttime
+ req
->timeout
;
820 te
= tevent_add_timer(ev
, ac
, tv
, lldb_timeout
, ac
);
822 return LDB_ERR_OPERATIONS_ERROR
;
828 static const struct ldb_module_ops lldb_ops
= {
830 .search
= lldb_handle_request
,
831 .add
= lldb_handle_request
,
832 .modify
= lldb_handle_request
,
833 .del
= lldb_handle_request
,
834 .rename
= lldb_handle_request
,
835 .request
= lldb_handle_request
,
836 .start_transaction
= lldb_start_trans
,
837 .end_transaction
= lldb_end_trans
,
838 .del_transaction
= lldb_del_trans
,
842 static int lldb_destructor(struct lldb_private
*lldb
)
844 ldap_unbind(lldb
->ldap
);
849 connect to the database
851 static int lldb_connect(struct ldb_context
*ldb
,
854 const char *options
[],
855 struct ldb_module
**_module
)
857 struct ldb_module
*module
;
858 struct lldb_private
*lldb
;
862 module
= ldb_module_new(ldb
, ldb
, "ldb_ldap backend", &lldb_ops
);
863 if (!module
) return LDB_ERR_OPERATIONS_ERROR
;
865 lldb
= talloc_zero(module
, struct lldb_private
);
870 ldb_module_set_private(module
, lldb
);
872 ret
= ldap_initialize(&lldb
->ldap
, url
);
873 if (ret
!= LDAP_SUCCESS
) {
874 ldb_debug(ldb
, LDB_DEBUG_FATAL
, "ldap_initialize failed for URL '%s' - %s",
875 url
, ldap_err2string(ret
));
879 talloc_set_destructor(lldb
, lldb_destructor
);
881 ret
= ldap_set_option(lldb
->ldap
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
882 if (ret
!= LDAP_SUCCESS
) {
883 ldb_debug(ldb
, LDB_DEBUG_FATAL
, "ldap_set_option failed - %s",
884 ldap_err2string(ret
));
893 return LDB_ERR_OPERATIONS_ERROR
;
896 const struct ldb_backend_ops ldb_ldap_backend_ops
= {
898 .connect_fn
= lldb_connect
901 const struct ldb_backend_ops ldb_ldapi_backend_ops
= {
903 .connect_fn
= lldb_connect
906 const struct ldb_backend_ops ldb_ldaps_backend_ops
= {
908 .connect_fn
= lldb_connect