diff options
Diffstat (limited to 'source4')
| -rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_index.c | 61 | ||||
| -rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_search.c | 129 | ||||
| -rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.c | 353 | ||||
| -rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.h | 14 | 
4 files changed, 242 insertions, 315 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index 269305a468..65711d9f4b 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -667,74 +667,58 @@ static int ltdb_index_dn(struct ldb_module *module,    extracting just the given attributes  */  static int ltdb_index_filter(const struct dn_list *dn_list,  -			     struct ldb_handle *handle) +			     struct ltdb_context *ac)  { -	struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); -	struct ldb_reply *ares = NULL; +	struct ldb_message *msg;  	unsigned int i;  	for (i = 0; i < dn_list->count; i++) {  		struct ldb_dn *dn;  		int ret; -		ares = talloc_zero(ac, struct ldb_reply); -		if (!ares) { -			handle->status = LDB_ERR_OPERATIONS_ERROR; -			handle->state = LDB_ASYNC_DONE; -			return LDB_ERR_OPERATIONS_ERROR; -		} - -		ares->message = ldb_msg_new(ares); -		if (!ares->message) { -			handle->status = LDB_ERR_OPERATIONS_ERROR; -			handle->state = LDB_ASYNC_DONE; -			talloc_free(ares); +		msg = ldb_msg_new(ac); +		if (!msg) {  			return LDB_ERR_OPERATIONS_ERROR;  		} - -		dn = ldb_dn_new(ares->message, ac->module->ldb, dn_list->dn[i]); +		dn = ldb_dn_new(msg, ac->module->ldb, dn_list->dn[i]);  		if (dn == NULL) { -			talloc_free(ares); +			talloc_free(msg);  			return LDB_ERR_OPERATIONS_ERROR;  		} -		ret = ltdb_search_dn1(ac->module, dn, ares->message); +		ret = ltdb_search_dn1(ac->module, dn, msg);  		talloc_free(dn);  		if (ret == LDB_ERR_NO_SUCH_OBJECT) {  			/* the record has disappeared? yes, this can happen */ -			talloc_free(ares); +			talloc_free(msg);  			continue;  		}  		if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {  			/* an internal error */ -			talloc_free(ares); +			talloc_free(msg);  			return LDB_ERR_OPERATIONS_ERROR;  		} -		if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, ac->base, ac->scope)) { -			talloc_free(ares); +		if (!ldb_match_msg(ac->module->ldb, msg, +				   ac->tree, ac->base, ac->scope)) { +			talloc_free(msg);  			continue;  		}  		/* filter the attributes that the user wants */ -		ret = ltdb_filter_attrs(ares->message, ac->attrs); +		ret = ltdb_filter_attrs(msg, ac->attrs);  		if (ret == -1) { -			handle->status = LDB_ERR_OPERATIONS_ERROR; -			handle->state = LDB_ASYNC_DONE; -			talloc_free(ares); +			talloc_free(msg);  			return LDB_ERR_OPERATIONS_ERROR;  		} -		ares->type = LDB_REPLY_ENTRY; -        	handle->state = LDB_ASYNC_PENDING; -		handle->status = ac->callback(ac->module->ldb, ac->context, ares); - -		if (handle->status != LDB_SUCCESS) { -			handle->state = LDB_ASYNC_DONE; -			return handle->status; +		ret = ldb_module_send_entry(ac->req, msg); +		if (ret != LDB_SUCCESS) { +			ac->callback_failed = true; +			return ret;  		}  	} @@ -746,9 +730,8 @@ static int ltdb_index_filter(const struct dn_list *dn_list,    returns -1 if an indexed search is not possible, in which    case the caller should call ltdb_search_full()   */ -int ltdb_search_indexed(struct ldb_handle *handle) +int ltdb_search_indexed(struct ltdb_context *ac)  { -	struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context);  	struct ltdb_private *ltdb = talloc_get_type(ac->module->private_data, struct ltdb_private);  	struct dn_list *dn_list;  	int ret, idxattr, idxone; @@ -773,7 +756,7 @@ int ltdb_search_indexed(struct ldb_handle *handle)  	ret = LDB_ERR_OPERATIONS_ERROR; -	dn_list = talloc_zero(handle, struct dn_list); +	dn_list = talloc_zero(ac, struct dn_list);  	if (dn_list == NULL) {  		return LDB_ERR_OPERATIONS_ERROR;  	} @@ -810,9 +793,7 @@ int ltdb_search_indexed(struct ldb_handle *handle)  	if (ret == LDB_SUCCESS) {  		/* we've got a candidate list - now filter by the full tree  		   and extract the needed attributes */ -		ret = ltdb_index_filter(dn_list, handle); -		handle->status = ret; -		handle->state = LDB_ASYNC_DONE; +		ret = ltdb_index_filter(dn_list, ac);  	}  	talloc_free(dn_list); diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index da899c361e..a220b4a628 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -395,71 +395,57 @@ int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs)   */  static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)  { -	struct ldb_handle *handle = talloc_get_type(state, struct ldb_handle); -	struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); -	struct ldb_reply *ares = NULL; +	struct ltdb_context *ac; +	struct ldb_message *msg;  	int ret; +	ac = talloc_get_type(state, struct ltdb_context); +  	if (key.dsize < 4 ||   	    strncmp((char *)key.dptr, "DN=", 3) != 0) {  		return 0;  	} -	ares = talloc_zero(ac, struct ldb_reply); -	if (!ares) { -		handle->status = LDB_ERR_OPERATIONS_ERROR; -		handle->state = LDB_ASYNC_DONE; -		return -1; -	} - -	ares->message = ldb_msg_new(ares); -	if (!ares->message) { -		handle->status = LDB_ERR_OPERATIONS_ERROR; -		handle->state = LDB_ASYNC_DONE; -		talloc_free(ares); +	msg = ldb_msg_new(ac); +	if (!msg) {  		return -1;  	}  	/* unpack the record */ -	ret = ltdb_unpack_data(ac->module, &data, ares->message); +	ret = ltdb_unpack_data(ac->module, &data, msg);  	if (ret == -1) { -		talloc_free(ares); +		talloc_free(msg);  		return -1;  	} -	if (!ares->message->dn) { -		ares->message->dn = ldb_dn_new(ares->message, ac->module->ldb, (char *)key.dptr + 3); -		if (ares->message->dn == NULL) { -			handle->status = LDB_ERR_OPERATIONS_ERROR; -			handle->state = LDB_ASYNC_DONE; -			talloc_free(ares); +	if (!msg->dn) { +		msg->dn = ldb_dn_new(msg, ac->module->ldb, +				     (char *)key.dptr + 3); +		if (msg->dn == NULL) { +			talloc_free(msg);  			return -1;  		}  	}  	/* see if it matches the given expression */ -	if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree,  -			       ac->base, ac->scope)) { -		talloc_free(ares); +	if (!ldb_match_msg(ac->module->ldb, msg, +			   ac->tree, ac->base, ac->scope)) { +		talloc_free(msg);  		return 0;  	}  	/* filter the attributes that the user wants */ -	ret = ltdb_filter_attrs(ares->message, ac->attrs); +	ret = ltdb_filter_attrs(msg, ac->attrs);  	if (ret == -1) { -		handle->status = LDB_ERR_OPERATIONS_ERROR; -		handle->state = LDB_ASYNC_DONE; -		talloc_free(ares); +		talloc_free(msg);  		return -1;  	} -	ares->type = LDB_REPLY_ENTRY; -        handle->state = LDB_ASYNC_PENDING; -	handle->status = ac->callback(ac->module->ldb, ac->context, ares); - -	if (handle->status != LDB_SUCCESS) { -		/* don't try to free ares here, the callback is in charge of that */ +	ret = ldb_module_send_entry(ac->req, msg); +	if (ret != LDB_SUCCESS) { +		ac->callback_failed = true; +		/* the callback failed, abort the operation */  		return -1;  	}	 @@ -471,23 +457,21 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi    search the database with a LDAP-like expression.    this is the "full search" non-indexed variant  */ -static int ltdb_search_full(struct ldb_handle *handle) +static int ltdb_search_full(struct ltdb_context *ctx)  { -	struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); -	struct ltdb_private *ltdb = talloc_get_type(ac->module->private_data, struct ltdb_private); +	struct ltdb_private *ltdb = talloc_get_type(ctx->module->private_data, struct ltdb_private);  	int ret;  	if (ltdb->in_transaction != 0) { -		ret = tdb_traverse(ltdb->tdb, search_func, handle); +		ret = tdb_traverse(ltdb->tdb, search_func, ctx);  	} else { -		ret = tdb_traverse_read(ltdb->tdb, search_func, handle); +		ret = tdb_traverse_read(ltdb->tdb, search_func, ctx);  	}  	if (ret == -1) { -		handle->status = LDB_ERR_OPERATIONS_ERROR; +		return LDB_ERR_OPERATIONS_ERROR;  	} -	handle->state = LDB_ASYNC_DONE;  	return LDB_SUCCESS;  } @@ -495,13 +479,15 @@ static int ltdb_search_full(struct ldb_handle *handle)    search the database with a LDAP-like expression.    choses a search method  */ -int ltdb_search(struct ldb_module *module, struct ldb_request *req) +int ltdb_search(struct ltdb_context *ctx)  { +	struct ldb_module *module = ctx->module; +	struct ldb_request *req = ctx->req;  	struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); -	struct ltdb_context *ltdb_ac; -	struct ldb_reply *ares;  	int ret; +	req->handle->state = LDB_ASYNC_PENDING; +  	if (ltdb_lock_read(module) != 0) {  		return LDB_ERR_OPERATIONS_ERROR;  	} @@ -516,12 +502,6 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)  		return LDB_ERR_OPERATIONS_ERROR;  	} -	req->handle = init_ltdb_handle(ltdb, module, req); -	if (req->handle == NULL) { -		ltdb_unlock_read(module); -		return LDB_ERR_OPERATIONS_ERROR; -	} -  	if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) {  		/* Check what we should do with a NULL dn */ @@ -564,53 +544,32 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)  		ret = LDB_SUCCESS;  	} -	ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); - -	ltdb_ac->tree = req->op.search.tree; -	ltdb_ac->scope = req->op.search.scope; -	ltdb_ac->base = req->op.search.base; -	ltdb_ac->attrs = req->op.search.attrs; - +	ctx->tree = req->op.search.tree; +	ctx->scope = req->op.search.scope; +	ctx->base = req->op.search.base; +	ctx->attrs = req->op.search.attrs;  	if (ret == LDB_SUCCESS) { -		ret = ltdb_search_indexed(req->handle); +		ret = ltdb_search_indexed(ctx);  		if (ret == LDB_ERR_NO_SUCH_OBJECT) {  			/* Not in the index, therefore OK! */  			ret = LDB_SUCCESS; -		} else if (ret == LDB_ERR_OPERATIONS_ERROR) { +		} +		/* Check if we got just a normal error. +		 * In that case proceed to a full search unless we got a +		 * callback error */ +		if ( ! ctx->callback_failed && ret != LDB_SUCCESS) {  			/* Not indexed, so we need to do a full scan */ -			ret = ltdb_search_full(req->handle); +			ret = ltdb_search_full(ctx);  			if (ret != LDB_SUCCESS) {  				ldb_set_errstring(module->ldb, "Indexed and full searches both failed!\n");  			}  		}  	} -	if (ret != LDB_SUCCESS) { -		req->handle->state = LDB_ASYNC_DONE; -		req->handle->status = ret; -	} - -	/* Finally send an LDB_REPLY_DONE packet when searching is finished */ - -	ares = talloc_zero(req, struct ldb_reply); -	if (!ares) { -		ltdb_unlock_read(module); -		return LDB_ERR_OPERATIONS_ERROR; -	} - -	req->handle->state = LDB_ASYNC_DONE; - -	if (ret == LDB_SUCCESS) { -		ares->type = LDB_REPLY_DONE; -		 -		ret = req->callback(module->ldb, req->context, ares); -		req->handle->status = ret; -	} -  	ltdb_unlock_read(module); -	return LDB_SUCCESS; +	return ret;  } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 01d570c89a..0087f6c44d 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -3,7 +3,7 @@     Copyright (C) Andrew Tridgell  2004     Copyright (C) Stefan Metzmacher  2004 -   Copyright (C) Simo Sorce       2006 +   Copyright (C) Simo Sorce       2006-2008       ** NOTE! The following LGPL license applies to the ldb @@ -39,6 +39,10 @@   *  - description: make the module use asyncronous calls   *    date: Feb 2006   *    Author: Simo Sorce + * + *  - description: make it possible to use event contexts + *    date: Jan 2008 + *    Author: Simo Sorce   */  #include "ldb_includes.h" @@ -76,40 +80,6 @@ static int ltdb_err_map(enum TDB_ERROR tdb_code)  } -struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, -				    struct ldb_module *module, -				    struct ldb_request *req) -{ -	struct ltdb_context *ac; -	struct ldb_handle *h; - -	h = talloc_zero(req, struct ldb_handle); -	if (h == NULL) { -		ldb_set_errstring(module->ldb, "Out of Memory"); -		return NULL; -	} - -	h->module = module; - -	ac = talloc_zero(h, struct ltdb_context); -	if (ac == NULL) { -		ldb_set_errstring(module->ldb, "Out of Memory"); -		talloc_free(h); -		return NULL; -	} - -	h->private_data = (void *)ac; - -	h->state = LDB_ASYNC_INIT; -	h->status = LDB_SUCCESS; - -	ac->module = module; -	ac->context = req->context; -	ac->callback = req->callback; - -	return h; -} -  /*    form a TDB_DATA for a record key    caller frees @@ -296,36 +266,20 @@ static int ltdb_add_internal(struct ldb_module *module,  /*    add a record to the database  */ -static int ltdb_add(struct ldb_module *module, struct ldb_request *req) +static int ltdb_add(struct ltdb_context *ctx)  { -	struct ltdb_private *ltdb; -	struct ltdb_context *ltdb_ac; -	int tret, ret = LDB_SUCCESS; - -	ltdb = talloc_get_type(module->private_data, struct ltdb_private); - -	if (check_critical_controls(req->controls)) { -		return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; -	} +	struct ldb_module *module = ctx->module; +	struct ldb_request *req = ctx->req; +	int tret; -	req->handle = init_ltdb_handle(ltdb, module, req); -	if (req->handle == NULL) { -		return LDB_ERR_OPERATIONS_ERROR; -	} -	ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); +	req->handle->state = LDB_ASYNC_PENDING;  	tret = ltdb_add_internal(module, req->op.add.message);  	if (tret != LDB_SUCCESS) { -		req->handle->status = tret; -		goto done; +		return tret;  	} -	if (ltdb_ac->callback) { -		ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); -	} -done: -	req->handle->state = LDB_ASYNC_DONE; -	return ret; +	return LDB_SUCCESS;  }  /* @@ -402,42 +356,24 @@ done:  /*    delete a record from the database  */ -static int ltdb_delete(struct ldb_module *module, struct ldb_request *req) +static int ltdb_delete(struct ltdb_context *ctx)  { -	struct ltdb_private *ltdb; -	struct ltdb_context *ltdb_ac; -	int tret, ret = LDB_SUCCESS; - -	ltdb = talloc_get_type(module->private_data, struct ltdb_private); - -	if (check_critical_controls(req->controls)) { -		return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; -	} +	struct ldb_module *module = ctx->module; +	struct ldb_request *req = ctx->req; +	int tret; -	req->handle = NULL; +	req->handle->state = LDB_ASYNC_PENDING;  	if (ltdb_cache_load(module) != 0) {  		return LDB_ERR_OPERATIONS_ERROR;  	} -	req->handle = init_ltdb_handle(ltdb, module, req); -	if (req->handle == NULL) { -		return LDB_ERR_OPERATIONS_ERROR; -	} -	ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); -  	tret = ltdb_delete_internal(module, req->op.del.dn);  	if (tret != LDB_SUCCESS) { -		req->handle->status = tret; -		goto done; +		return tret;  	} -	if (ltdb_ac->callback) { -		ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); -	} -done: -	req->handle->state = LDB_ASYNC_DONE; -	return ret; +	return LDB_SUCCESS;  }  /* @@ -784,83 +720,50 @@ failed:  /*    modify a record  */ -static int ltdb_modify(struct ldb_module *module, struct ldb_request *req) +static int ltdb_modify(struct ltdb_context *ctx)  { -	struct ltdb_private *ltdb; -	struct ltdb_context *ltdb_ac; -	int tret, ret = LDB_SUCCESS; - -	ltdb = talloc_get_type(module->private_data, struct ltdb_private); - -	if (check_critical_controls(req->controls)) { -		return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; -	} - -	req->handle = NULL; +	struct ldb_module *module = ctx->module; +	struct ldb_request *req = ctx->req; +	int tret; -	req->handle = init_ltdb_handle(ltdb, module, req); -	if (req->handle == NULL) { -		return LDB_ERR_OPERATIONS_ERROR; -	} -	ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); +	req->handle->state = LDB_ASYNC_PENDING;  	tret = ltdb_check_special_dn(module, req->op.mod.message);  	if (tret != LDB_SUCCESS) { -		req->handle->status = tret; -		goto done; +		return tret;  	}  	if (ltdb_cache_load(module) != 0) { -		ret = LDB_ERR_OPERATIONS_ERROR; -		goto done; +		return LDB_ERR_OPERATIONS_ERROR;  	}  	tret = ltdb_modify_internal(module, req->op.mod.message);  	if (tret != LDB_SUCCESS) { -		req->handle->status = tret; -		goto done; +		return tret;  	} -	if (ltdb_ac->callback) { -		ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); -	} -done: -	req->handle->state = LDB_ASYNC_DONE; -	return ret; +	return LDB_SUCCESS;  }  /*    rename a record  */ -static int ltdb_rename(struct ldb_module *module, struct ldb_request *req) +static int ltdb_rename(struct ltdb_context *ctx)  { -	struct ltdb_private *ltdb; -	struct ltdb_context *ltdb_ac; +	struct ldb_module *module = ctx->module; +	struct ldb_request *req = ctx->req;  	struct ldb_message *msg; -	int tret, ret = LDB_SUCCESS; - -	ltdb = talloc_get_type(module->private_data, struct ltdb_private); - -	if (check_critical_controls(req->controls)) { -		return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; -	} - -	req->handle = NULL; +	int tret; -	if (ltdb_cache_load(module) != 0) { -		return LDB_ERR_OPERATIONS_ERROR; -	} +	req->handle->state = LDB_ASYNC_PENDING; -	req->handle = init_ltdb_handle(ltdb, module, req); -	if (req->handle == NULL) { +	if (ltdb_cache_load(ctx->module) != 0) {  		return LDB_ERR_OPERATIONS_ERROR;  	} -	ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); -	msg = talloc(ltdb_ac, struct ldb_message); +	msg = talloc(ctx, struct ldb_message);  	if (msg == NULL) { -		ret = LDB_ERR_OPERATIONS_ERROR; -		goto done; +		return LDB_ERR_OPERATIONS_ERROR;  	}  	/* in case any attribute of the message was indexed, we need @@ -868,14 +771,12 @@ static int ltdb_rename(struct ldb_module *module, struct ldb_request *req)  	tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);  	if (tret != LDB_SUCCESS) {  		/* not finding the old record is an error */ -		req->handle->status = tret; -		goto done; +		return tret;  	}  	msg->dn = ldb_dn_copy(msg, req->op.rename.newdn);  	if (!msg->dn) { -		ret = LDB_ERR_OPERATIONS_ERROR; -		goto done; +		return LDB_ERR_OPERATIONS_ERROR;  	}  	if (ldb_dn_compare(req->op.rename.olddn, req->op.rename.newdn) == 0) { @@ -886,38 +787,32 @@ static int ltdb_rename(struct ldb_module *module, struct ldb_request *req)  		   The only drawback to this is that if the delete  		   succeeds but the add fails, we rely on the  		   transaction to roll this all back. */ -		ret = ltdb_delete_internal(module, req->op.rename.olddn); -		if (ret != LDB_SUCCESS) { -			goto done; +		tret = ltdb_delete_internal(module, req->op.rename.olddn); +		if (tret != LDB_SUCCESS) { +			return tret;  		} -		ret = ltdb_add_internal(module, msg); -		if (ret != LDB_SUCCESS) { -			goto done; +		tret = ltdb_add_internal(module, msg); +		if (tret != LDB_SUCCESS) { +			return tret;  		}  	} else {  		/* The rename operation is changing DNs.  Try to add the new  		   DN first to avoid clobbering another DN not related to  		   this rename operation. */ -		ret = ltdb_add_internal(module, msg); -		if (ret != LDB_SUCCESS) { -			goto done; +		tret = ltdb_add_internal(module, msg); +		if (tret != LDB_SUCCESS) { +			return tret;  		}  		tret = ltdb_delete_internal(module, req->op.rename.olddn);  		if (tret != LDB_SUCCESS) {  			ltdb_delete_internal(module, req->op.rename.newdn); -			ret = LDB_ERR_OPERATIONS_ERROR; -			goto done; +			return LDB_ERR_OPERATIONS_ERROR;  		}  	} -	if (ltdb_ac->callback) { -		ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); -	} -done: -	req->handle->state = LDB_ASYNC_DONE; -	return ret; +	return LDB_SUCCESS;  }  static int ltdb_start_trans(struct ldb_module *module) @@ -962,24 +857,6 @@ static int ltdb_del_trans(struct ldb_module *module)  	return LDB_SUCCESS;  } -static int ltdb_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ -	return handle->status; -} - -static int ltdb_request(struct ldb_module *module, struct ldb_request *req) -{ -	/* check for oustanding critical controls -	 * and return an error if found */ -	if (check_critical_controls(req->controls)) { -		return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; -	} - -	/* search, add, modify, delete, rename are handled by their own, -	 * no other op supported */ -	return LDB_ERR_OPERATIONS_ERROR; -} -  /*    return sequenceNumber from @BASEINFO  */ @@ -1013,7 +890,7 @@ static int ltdb_sequence_number(struct ldb_module *module,  		talloc_free(tmp_ctx);  		/* zero is as good as anything when we don't know */  		req->op.seq_num.seq_num = 0; -		return LDB_SUCCESS; +		return tret;  	}  	switch (req->op.seq_num.type) { @@ -1034,22 +911,136 @@ static int ltdb_sequence_number(struct ldb_module *module,  		}  		break;  	} +  	talloc_free(tmp_ctx); + +	return LDB_SUCCESS; +} + +void ltdb_request_done(struct ldb_request *req, int error) +{ +	struct ldb_reply *ares; + +	/* if we already returned an error just return */ +	if (req->handle->status != LDB_SUCCESS) { +		return; +	} + +	ares = talloc_zero(req, struct ldb_reply); +	if (!ares) { +		ldb_oom(req->handle->ldb); +		req->callback(req, NULL); +		return; +	} +	ares->type = LDB_REPLY_DONE; +	ares->error = error; + +	req->callback(req, ares); +} + +static void ltdb_timeout(struct event_context *ev, +			  struct timed_event *te, +			  struct timeval t, +			  void *private_data) +{ +	struct ltdb_context *ctx; +	ctx = talloc_get_type(private_data, struct ltdb_context); + +	ltdb_request_done(ctx->req, LDB_ERR_TIME_LIMIT_EXCEEDED); +} + +static void ltdb_callback(struct event_context *ev, +			  struct timed_event *te, +			  struct timeval t, +			  void *private_data) +{ +	struct ltdb_context *ctx; +	int ret; + +	ctx = talloc_get_type(private_data, struct ltdb_context); + +	switch (ctx->req->operation) { +	case LDB_SEARCH: +		ret = ltdb_search(ctx); +		break; +	case LDB_ADD: +		ret = ltdb_add(ctx); +		break; +	case LDB_MODIFY: +		ret = ltdb_modify(ctx); +		break; +	case LDB_DELETE: +		ret = ltdb_delete(ctx); +		break; +	case LDB_RENAME: +		ret = ltdb_rename(ctx); +		break; +	default: +		/* no other op supported */ +		ret = LDB_ERR_UNWILLING_TO_PERFORM; +	} + +	if (!ctx->callback_failed) { +		ltdb_request_done(ctx->req, ret); +	} +} + +static int ltdb_handle_request(struct ldb_module *module, +				struct ldb_request *req) +{ +	struct event_context *ev; +	struct ltdb_context *ac; +	struct timed_event *te; +	struct timeval tv; + +	if (check_critical_controls(req->controls)) { +		return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; +	} + +	if (req->starttime == 0 || req->timeout == 0) { +		ldb_set_errstring(module->ldb, "Invalid timeout settings"); +		return LDB_ERR_TIME_LIMIT_EXCEEDED; +	} + +	ev = ldb_get_event_context(module->ldb); + +	ac = talloc_zero(req, struct ltdb_context); +	if (ac == NULL) { +		ldb_set_errstring(module->ldb, "Out of Memory"); +		return LDB_ERR_OPERATIONS_ERROR; +	} + +	ac->module = module; +	ac->req = req; + +	tv.tv_sec = 0; +	tv.tv_usec = 0; +	te = event_add_timed(ev, ac, tv, ltdb_callback, ac); +	if (NULL == te) { +		return LDB_ERR_OPERATIONS_ERROR; +	} + + +	tv.tv_sec = req->starttime + req->timeout; +	te = event_add_timed(ev, ac, tv, ltdb_timeout, ac); +	if (NULL == te) { +		return LDB_ERR_OPERATIONS_ERROR; +	} +  	return LDB_SUCCESS;  }  static const struct ldb_module_ops ltdb_ops = {  	.name              = "tdb", -	.search            = ltdb_search, -	.add               = ltdb_add, -	.modify            = ltdb_modify, -	.del               = ltdb_delete, -	.rename            = ltdb_rename, -	.request           = ltdb_request, +	.search            = ltdb_handle_request, +	.add               = ltdb_handle_request, +	.modify            = ltdb_handle_request, +	.del               = ltdb_handle_request, +	.rename            = ltdb_handle_request, +/*	.request           = ltdb_handle_request, */  	.start_transaction = ltdb_start_trans,  	.end_transaction   = ltdb_end_trans,  	.del_transaction   = ltdb_del_trans, -	.wait              = ltdb_wait,  	.sequence_number   = ltdb_sequence_number  }; @@ -1114,7 +1105,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,  	ltdb->sequence_number = 0;  	*module = talloc(ldb, struct ldb_module); -	if (!module) { +	if ((*module) == NULL) {  		ldb_oom(ldb);  		talloc_free(ltdb);  		return -1; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 4beced30eb..223181ca0b 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -41,16 +41,15 @@ struct ltdb_private {  */  struct ltdb_context {  	struct ldb_module *module; +	struct ldb_request *req; + +	bool callback_failed;  	/* search stuff */  	const struct ldb_parse_tree *tree;  	struct ldb_dn *base;  	enum ldb_scope scope;  	const char * const *attrs; - -	/* async stuff */ -	void *context; -	int (*callback)(struct ldb_context *, void *, struct ldb_reply *);  };  /* special record types */ @@ -80,7 +79,7 @@ int ltdb_check_at_attributes_values(const struct ldb_val *value);  struct ldb_parse_tree; -int ltdb_search_indexed(struct ldb_handle *handle); +int ltdb_search_indexed(struct ltdb_context *ctx);  int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg);  int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg);  int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add); @@ -110,11 +109,9 @@ int ltdb_add_attr_results(struct ldb_module *module,  			  unsigned int *count,   			  struct ldb_message ***res);  int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs); -int ltdb_search(struct ldb_module *module, struct ldb_request *req); +int ltdb_search(struct ltdb_context *ctx);  /* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c  */ -struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module, -				    struct ldb_request *req);  struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn);  int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs);  int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn); @@ -127,4 +124,3 @@ struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx,  				   const char *path, int hash_size, int tdb_flags,  				   int open_flags, mode_t mode,  				   struct ldb_context *ldb); -  | 
