*
* Modifications:
*
- * - description: make the module use asyncronous calls
+ * - description: make the module use asynchronous calls
* date: Feb 2006
* author: Simo Sorce
*/
-
#include "includes.h"
-#include "ldb_includes.h"
+#include "ldb_module.h"
+#include "dlinklist.h"
-#include "lib/events/events.h"
#include "libcli/ldap/ldap.h"
#include "libcli/ldap/ldap_client.h"
#include "auth/auth.h"
#include "auth/credentials/credentials.h"
-#include "param/param.h"
struct ildb_private {
struct ldap_connection *ldap;
- struct event_context *event_ctx;
+ struct tevent_context *event_ctx;
};
struct ildb_context {
struct ildb_private *ildb;
struct ldap_request *ireq;
+ /* indicate we are already processing
+ * the ldap_request in ildb_callback() */
+ bool in_ildb_callback;
+
bool done;
struct ildb_destructor_ctx *dc;
static void ildb_request_done(struct ildb_context *ctx,
struct ldb_control **ctrls, int error)
{
+ struct ldb_context *ldb;
struct ldb_reply *ares;
+ ldb = ldb_module_get_ctx(ctx->module);
+
ctx->done = true;
if (ctx->req == NULL) {
ares = talloc_zero(ctx->req, struct ldb_reply);
if (!ares) {
- ldb_oom(ctx->req->handle->ldb);
+ ldb_oom(ldb);
ctx->req->callback(ctx->req, NULL);
return;
}
ctx->req->callback(ctx->req, ares);
}
-static void ildb_auto_done_callback(struct event_context *ev,
- struct timed_event *te,
+static void ildb_auto_done_callback(struct tevent_context *ev,
+ struct tevent_timer *te,
struct timeval t,
void *private_data)
{
*/
static int ildb_map_error(struct ldb_module *module, NTSTATUS status)
{
- struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private);
+ struct ildb_private *ildb;
+ struct ldb_context *ldb;
+ TALLOC_CTX *mem_ctx;
+
+ ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private);
+ ldb = ldb_module_get_ctx(module);
- TALLOC_CTX *mem_ctx = talloc_new(ildb);
if (NT_STATUS_IS_OK(status)) {
return LDB_SUCCESS;
}
+
+ mem_ctx = talloc_new(ildb);
if (!mem_ctx) {
- ldb_oom(module->ldb);
+ ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- ldb_set_errstring(module->ldb,
+ ldb_set_errstring(ldb,
ldap_errstr(ildb->ldap, mem_ctx, status));
talloc_free(mem_ctx);
if (NT_STATUS_IS_LDAP(status)) {
return LDB_ERR_OPERATIONS_ERROR;
}
-static void ildb_request_timeout(struct event_context *ev, struct timed_event *te,
+static void ildb_request_timeout(struct tevent_context *ev, struct tevent_timer *te,
struct timeval t, void *private_data)
{
struct ildb_context *ac = talloc_get_type(private_data, struct ildb_context);
static void ildb_callback(struct ldap_request *req)
{
+ struct ldb_context *ldb;
struct ildb_context *ac;
NTSTATUS status;
struct ldap_SearchResEntry *search;
int i;
ac = talloc_get_type(req->async.private_data, struct ildb_context);
+ ldb = ldb_module_get_ctx(ac->module);
callback_failed = false;
request_done = false;
controls = NULL;
+ /* check if we are already processing this request */
+ if (ac->in_ildb_callback) {
+ return;
+ }
+ /* mark the request as being in process */
+ ac->in_ildb_callback = true;
+
if (!NT_STATUS_IS_OK(req->status)) {
ret = ildb_map_error(ac->module, req->status);
ildb_request_done(ac, NULL, ret);
controls = talloc_steal(ac, msg->controls);
if (msg->r.SearchResultDone.resultcode) {
if (msg->r.SearchResultDone.errormessage) {
- ldb_set_errstring(ac->module->ldb, msg->r.SearchResultDone.errormessage);
+ ldb_set_errstring(ldb, msg->r.SearchResultDone.errormessage);
}
}
search = &(msg->r.SearchResultEntry);
- ldbmsg->dn = ldb_dn_new(ldbmsg, ac->module->ldb, search->dn);
+ ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, search->dn);
if ( ! ldb_dn_validate(ldbmsg->dn)) {
ret = LDB_ERR_OPERATIONS_ERROR;
break;
ldbmsg->num_elements = search->num_attributes;
ldbmsg->elements = talloc_move(ldbmsg, &search->attributes);
- ret = ldb_module_send_entry(ac->req, ldbmsg);
+ controls = talloc_steal(ac, msg->controls);
+
+ ret = ldb_module_send_entry(ac->req, ldbmsg, controls);
if (ret != LDB_SUCCESS) {
callback_failed = true;
}
+
break;
case LDAP_TAG_SearchResultReference:
if (ret != LDB_SUCCESS) {
callback_failed = true;
}
+
break;
default:
}
}
+ /* mark the request as not being in progress */
+ ac->in_ildb_callback = false;
+
if (request_done) {
ildb_request_done(ac, controls, ret);
}
+
return;
}
static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg)
{
+ struct ldb_context *ldb;
struct ldap_request *req;
if (!ac) {
return LDB_ERR_OPERATIONS_ERROR;
}
+ ldb = ldb_module_get_ctx(ac->module);
+
req = ldap_request_send(ac->ildb->ldap, msg);
if (req == NULL) {
- ldb_set_errstring(ac->module->ldb, "async send request failed");
+ ldb_set_errstring(ldb, "async send request failed");
return LDB_ERR_OPERATIONS_ERROR;
}
ac->ireq = talloc_steal(ac, req);
if (!ac->ireq->conn) {
- ldb_set_errstring(ac->module->ldb, "connection to remote LDAP server dropped?");
+ ldb_set_errstring(ldb, "connection to remote LDAP server dropped?");
return LDB_ERR_OPERATIONS_ERROR;
}
talloc_free(req->time_event);
req->time_event = NULL;
if (ac->req->timeout) {
- req->time_event = event_add_timed(ac->ildb->event_ctx, ac,
- timeval_current_ofs(ac->req->timeout, 0),
- ildb_request_timeout, ac);
+ req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac,
+ timeval_current_ofs(ac->req->timeout, 0),
+ ildb_request_timeout, ac);
}
req->async.fn = ildb_callback;
*/
static int ildb_search(struct ildb_context *ac)
{
+ struct ldb_context *ldb;
struct ldb_request *req = ac->req;
struct ldap_message *msg;
int n;
+ ldb = ldb_module_get_ctx(ac->module);
+
if (!req->callback || !req->context) {
- ldb_set_errstring(ac->module->ldb, "Async interface called with NULL callback function or NULL context");
+ ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context");
return LDB_ERR_OPERATIONS_ERROR;
}
if (req->op.search.tree == NULL) {
- ldb_set_errstring(ac->module->ldb, "Invalid expression parse tree");
+ ldb_set_errstring(ldb, "Invalid expression parse tree");
return LDB_ERR_OPERATIONS_ERROR;
}
msg = new_ldap_message(req);
if (msg == NULL) {
- ldb_set_errstring(ac->module->ldb, "Out of Memory");
+ ldb_set_errstring(ldb, "Out of Memory");
return LDB_ERR_OPERATIONS_ERROR;
}
if (req->op.search.base == NULL) {
msg->r.SearchRequest.basedn = talloc_strdup(msg, "");
} else {
- msg->r.SearchRequest.basedn = ldb_dn_alloc_linearized(msg, req->op.search.base);
+ msg->r.SearchRequest.basedn = ldb_dn_get_extended_linearized(msg, req->op.search.base, 0);
}
if (msg->r.SearchRequest.basedn == NULL) {
- ldb_set_errstring(ac->module->ldb, "Unable to determine baseDN");
+ ldb_set_errstring(ldb, "Unable to determine baseDN");
talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
for (n = 0; req->op.search.attrs && req->op.search.attrs[n]; n++) /* noop */ ;
msg->r.SearchRequest.num_attributes = n;
- msg->r.SearchRequest.attributes = discard_const(req->op.search.attrs);
+ msg->r.SearchRequest.attributes = req->op.search.attrs;
msg->controls = req->controls;
return ildb_request_send(ac, msg);
msg->type = LDAP_TAG_AddRequest;
- msg->r.AddRequest.dn = ldb_dn_alloc_linearized(msg, req->op.add.message->dn);
+ msg->r.AddRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.add.message->dn, 0);
if (msg->r.AddRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
for (i = 0; i < n; i++) {
msg->r.AddRequest.attributes[i] = mods[i]->attrib;
}
+ msg->controls = req->controls;
return ildb_request_send(ac, msg);
}
msg->type = LDAP_TAG_ModifyRequest;
- msg->r.ModifyRequest.dn = ldb_dn_alloc_linearized(msg, req->op.mod.message->dn);
+ msg->r.ModifyRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.mod.message->dn, 0);
if (msg->r.ModifyRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
for (i = 0; i < n; i++) {
msg->r.ModifyRequest.mods[i] = *mods[i];
}
-
+ msg->controls = req->controls;
return ildb_request_send(ac, msg);
}
msg->type = LDAP_TAG_DelRequest;
- msg->r.DelRequest.dn = ldb_dn_alloc_linearized(msg, req->op.del.dn);
+ msg->r.DelRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.del.dn, 0);
if (msg->r.DelRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
}
+ msg->controls = req->controls;
return ildb_request_send(ac, msg);
}
{
struct ldb_request *req = ac->req;
struct ldap_message *msg;
+ const char *rdn_name;
+ const struct ldb_val *rdn_val;
msg = new_ldap_message(req);
if (msg == NULL) {
}
msg->type = LDAP_TAG_ModifyDNRequest;
- msg->r.ModifyDNRequest.dn = ldb_dn_alloc_linearized(msg, req->op.rename.olddn);
+ msg->r.ModifyDNRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.rename.olddn, 0);
if (msg->r.ModifyDNRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
}
- msg->r.ModifyDNRequest.newrdn =
- talloc_asprintf(msg, "%s=%s",
- ldb_dn_get_rdn_name(req->op.rename.newdn),
- ldb_dn_escape_value(msg, *ldb_dn_get_rdn_val(req->op.rename.newdn)));
+ rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn);
+ rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn);
+
+ if ((rdn_name != NULL) && (rdn_val != NULL)) {
+ msg->r.ModifyDNRequest.newrdn =
+ talloc_asprintf(msg, "%s=%s", rdn_name,
+ ldb_dn_escape_value(msg, *rdn_val));
+ } else {
+ msg->r.ModifyDNRequest.newrdn = talloc_strdup(msg, "");
+ }
if (msg->r.ModifyDNRequest.newrdn == NULL) {
talloc_free(msg);
return LDB_ERR_OPERATIONS_ERROR;
}
msg->r.ModifyDNRequest.deleteolddn = true;
+ msg->controls = req->controls;
return ildb_request_send(ac, msg);
}
static int ildb_handle_request(struct ldb_module *module, struct ldb_request *req)
{
+ struct ldb_context *ldb;
struct ildb_private *ildb;
struct ildb_context *ac;
- struct timed_event *te;
+ struct tevent_timer *te;
int ret;
- ildb = talloc_get_type(module->private_data, struct ildb_private);
+ ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private);
+ ldb = ldb_module_get_ctx(module);
if (req->starttime == 0 || req->timeout == 0) {
- ldb_set_errstring(module->ldb, "Invalid timeout settings");
+ ldb_set_errstring(ldb, "Invalid timeout settings");
return LDB_ERR_TIME_LIMIT_EXCEEDED;
}
ac = talloc_zero(req, struct ildb_context);
if (ac == NULL) {
- ldb_set_errstring(module->ldb, "Out of Memory");
+ ldb_set_errstring(ldb, "Out of Memory");
return LDB_ERR_OPERATIONS_ERROR;
}
if (ildb_dn_is_special(req)) {
- te = event_add_timed(ac->ildb->event_ctx,
- ac, timeval_zero(),
- ildb_auto_done_callback, ac);
+ te = tevent_add_timer(ac->ildb->event_ctx,
+ ac, timeval_zero(),
+ ildb_auto_done_callback, ac);
if (NULL == te) {
return LDB_ERR_OPERATIONS_ERROR;
}
struct ildb_private *ildb;
NTSTATUS status;
struct cli_credentials *creds;
+ struct loadparm_context *lp_ctx;
- module = talloc(ldb, struct ldb_module);
- if (!module) {
- ldb_oom(ldb);
- return -1;
- }
- talloc_set_name_const(module, "ldb_ildap backend");
- module->ldb = ldb;
- module->prev = module->next = NULL;
- module->ops = &ildb_ops;
+ module = ldb_module_new(ldb, ldb, "ldb_ildap backend", &ildb_ops);
+ if (!module) return LDB_ERR_OPERATIONS_ERROR;
ildb = talloc(module, struct ildb_private);
if (!ildb) {
ldb_oom(ldb);
goto failed;
}
- module->private_data = ildb;
+ ldb_module_set_private(module, ildb);
ildb->event_ctx = ldb_get_event_context(ldb);
+ lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
+ struct loadparm_context);
- ildb->ldap = ldap4_new_connection(ildb, ldb_get_opaque(ldb, "loadparm"),
+ ildb->ldap = ldap4_new_connection(ildb, lp_ctx,
ildb->event_ctx);
if (!ildb->ldap) {
ldb_oom(ldb);
status = ldap_connect(ildb->ldap, url);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s",
url, ldap_errstr(ildb->ldap, module, status));
goto failed;
}
const char *password = cli_credentials_get_password(creds);
status = ldap_bind_simple(ildb->ldap, bind_dn, password);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
ldap_errstr(ildb->ldap, module, status));
goto failed;
}
} else {
- status = ldap_bind_sasl(ildb->ldap, creds, ldb_get_opaque(ldb, "loadparm"));
+ status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
ldap_errstr(ildb->ldap, module, status));
goto failed;
}
}
*_module = module;
- return 0;
+ return LDB_SUCCESS;
failed:
talloc_free(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
_PUBLIC_ const struct ldb_backend_ops ldb_ldap_backend_ops = {