1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r13609: Get in the initial work on making ldb async

Currently only ldb_ildap is async, the plan
is to first make all backend support the async calls,
and then remove the sync functions from backends and
keep the only in the API.

Modules will need to be transformed along the way.

Simo
(This used to be commit 1e2c13b2d5)
This commit is contained in:
Simo Sorce 2006-02-22 01:31:35 +00:00 committed by Gerald (Jerry) Carter
parent f490434c0f
commit 00fe70e5b9
17 changed files with 875 additions and 362 deletions

View File

@ -44,44 +44,6 @@ static int map_ldb_error(struct ldb_context *ldb, int err, const char **errstrin
return err;
}
/*
map controls
*/
static int get_ldb_controls(void *mem_ctx, struct ldap_Control **controls, struct ldb_control ***lcontrols)
{
struct ldb_control **lctrl;
int i, l;
if (controls == NULL || controls[0] == NULL) {
*lcontrols = NULL;
return LDB_SUCCESS;
}
l = 0;
lctrl = NULL;
*lcontrols = NULL;
for (i = 0; controls[i] != NULL; i++) {
lctrl = talloc_realloc(mem_ctx, lctrl, struct ldb_control *, l + 2);
if (lctrl == NULL) {
return LDB_ERR_OTHER;
}
lctrl[l] = talloc(lctrl, struct ldb_control);
if (lctrl[l] == NULL) {
return LDB_ERR_OTHER;
}
lctrl[l]->oid = controls[i]->oid;
lctrl[l]->critical = controls[i]->critical;
lctrl[l]->data = controls[i]->value;
l++;
}
lctrl[l] = NULL;
*lcontrols = lctrl;
return LDB_SUCCESS;
}
/*
connect to the sam database
*/
@ -217,14 +179,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
lreq.op.search.tree = req->tree;
lreq.op.search.attrs = attrs;
ldb_ret = get_ldb_controls(local_ctx, call->request->controls, &lreq.controls);
if (ldb_ret != LDB_SUCCESS) {
/* get_ldb_controls fails only on a critical internal error or when
* a control is defined as critical but it is not supported
*/
goto reply;
}
lreq.controls = call->request->controls;
ldb_ret = ldb_request(samdb, &lreq);
@ -281,7 +236,7 @@ reply:
errstr = ldb_errstring(samdb);
}
if (res->controls) {
done_r->msg->controls = (struct ldap_Control **)(res->controls);
done_r->msg->controls = res->controls;
talloc_steal(done_r, res->controls);
}
} else {

View File

@ -106,7 +106,15 @@ int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, co
return LDB_SUCCESS;
}
static void ldb_reset_err_string(struct ldb_context *ldb)
void ldb_set_errstring(struct ldb_module *module, char *err_string)
{
if (module->ldb->err_string) {
talloc_free(module->ldb->err_string);
}
module->ldb->err_string = talloc_steal(module->ldb, err_string);
}
void ldb_reset_err_string(struct ldb_context *ldb)
{
if (ldb->err_string) {
talloc_free(ldb->err_string);
@ -211,6 +219,14 @@ int ldb_transaction_cancel(struct ldb_context *ldb)
return status;
}
int ldb_async_wait(struct ldb_context *ldb, struct ldb_async_handle *handle, enum ldb_async_wait_type type)
{
if (ldb->async_wait != NULL)
return ldb->async_wait(handle, type);
return LDB_ERR_OPERATIONS_ERROR;
}
/*
check for an error return from an op
if an op fails, but has not setup an error string, then setup one now
@ -279,6 +295,9 @@ int ldb_request(struct ldb_context *ldb, struct ldb_request *request)
if (request->operation == LDB_REQ_SEARCH) {
request->op.search.res = talloc_steal(ldb, r->op.search.res);
}
if (request->operation == LDB_ASYNC_SEARCH) {
request->async.handle = r->async.handle;
}
talloc_free(r);
if (started_transaction) {

View File

@ -263,13 +263,3 @@ int ldb_next_del_trans(struct ldb_module *module)
FIND_OP(module, del_transaction);
return module->ops->del_transaction(module);
}
void ldb_set_errstring(struct ldb_module *module, char *err_string)
{
if (module->ldb->err_string) {
talloc_free(module->ldb->err_string);
}
module->ldb->err_string = talloc_steal(module->ldb, err_string);
}

View File

@ -560,15 +560,51 @@ enum ldb_request_type {
LDB_REQ_MODIFY,
LDB_REQ_DELETE,
LDB_REQ_RENAME,
LDB_ASYNC_SEARCH,
LDB_ASYNC_ADD,
LDB_ASYNC_MODIFY,
LDB_ASYNC_DELETE,
LDB_ASYNC_RENAME,
LDB_REQ_REGISTER
};
enum ldb_reply_type {
LDB_REPLY_ENTRY,
LDB_REPLY_REFERRAL,
LDB_REPLY_DONE
};
enum ldb_async_wait_type {
LDB_WAIT_ALL,
LDB_WAIT_NONE
};
enum ldb_async_state {
LDB_ASYNC_PENDING,
LDB_ASYNC_DONE
};
struct ldb_result {
unsigned int count;
struct ldb_message **msgs;
char **refs;
struct ldb_control **controls;
};
struct ldb_async_result {
enum ldb_reply_type type;
struct ldb_message *message;
char *referral;
struct ldb_control **controls;
};
struct ldb_async_handle {
int status;
enum ldb_async_state state;
void *private_data;
};
struct ldb_search {
const struct ldb_dn *base;
enum ldb_scope scope;
@ -613,10 +649,20 @@ struct ldb_request {
struct ldb_control **controls;
struct ldb_credentials *creds;
struct {
void *context;
int (*callback)(struct ldb_context *, void *, struct ldb_async_result *);
time_t timeout;
struct ldb_async_handle *handle;
} async;
};
int ldb_request(struct ldb_context *ldb, struct ldb_request *request);
int ldb_async_wait(struct ldb_context *ldb, struct ldb_async_handle *handle, enum ldb_async_wait_type type);
/**
Initialise an ldb context

View File

@ -105,6 +105,8 @@ struct ldb_context {
char *err_string;
int transaction_active;
int (*async_wait)(struct ldb_async_handle *, enum ldb_async_wait_type);
};
/* the modules init function */
@ -132,6 +134,7 @@ int ldb_next_del_trans(struct ldb_module *module);
int ldb_next_second_stage_init(struct ldb_module *module);
void ldb_set_errstring(struct ldb_module *module, char *err_string);
void ldb_reset_err_string(struct ldb_context *ldb);
/* The following definitions come from lib/ldb/common/ldb_debug.c */
void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);

File diff suppressed because it is too large Load Diff

View File

@ -964,6 +964,7 @@ static int lsqlite3_search_bytree(struct ldb_module * module, const struct ldb_d
(*res)->msgs = talloc_steal(*res, msgs.msgs);
(*res)->count = msgs.count;
(*res)->refs = NULL;
(*res)->controls = NULL;
talloc_free(local_ctx);

View File

@ -709,6 +709,7 @@ int ltdb_search_indexed(struct ldb_module *module,
}
(*res)->count = 0;
(*res)->msgs = NULL;
(*res)->refs = NULL;
(*res)->controls = NULL;
if (scope == LDB_SCOPE_BASE) {

View File

@ -441,6 +441,7 @@ static int ltdb_search_full(struct ldb_module *module,
}
result->controls = NULL;
result->refs = NULL;
result->msgs = talloc_steal(result, sinfo->msgs);
result->count = sinfo->count;
*res = result;

View File

@ -596,10 +596,6 @@ int handle_controls_reply(struct ldb_control **reply, struct ldb_control **reque
cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len);
printf("# DIRSYNC cookie returned was:\n# %s\n", cookie);
sleep(120);
ret = 1;
continue;
}

View File

@ -64,9 +64,10 @@ static int do_search(struct ldb_context *ldb,
const char *expression,
const char * const *attrs)
{
int ret, i;
int ret, i, n;
int loop = 0;
int total = 0;
int refs = 0;
struct ldb_request req;
struct ldb_result *result = NULL;
@ -94,7 +95,6 @@ static int do_search(struct ldb_context *ldb,
}
result = req.op.search.res;
printf("# returned %d records\n", result->count);
if (options->sorted) {
ldb_qsort(result->msgs, result->count, sizeof(struct ldb_message *),
@ -120,6 +120,12 @@ static int do_search(struct ldb_context *ldb,
ldb_ldif_write_file(ldb, stdout, &ldif);
}
if (result->refs) {
for(n = 0;result->refs[n]; n++, refs++) {
printf("# referral %d\nref: %s\n\n", refs + 1, result->refs[n]);
}
}
if (result->controls) {
if (handle_controls_reply(result->controls, req.controls) == 1)
loop = 1;
@ -137,6 +143,8 @@ static int do_search(struct ldb_context *ldb,
} while(loop);
printf("# returned %d records\n# %d entries\n# %d referrals\n", total + refs, total, refs);
return 0;
}

View File

@ -1309,19 +1309,19 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg)
if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
int i;
struct ldap_Control **ctrl = NULL;
struct ldb_control **ctrl = NULL;
asn1_start_tag(data, ASN1_CONTEXT(0));
for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) {
/* asn1_start_tag(data, ASN1_SEQUENCE(0)); */
ctrl = talloc_realloc(msg, ctrl, struct ldap_Control *, i+2);
ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2);
if (!ctrl) {
return False;
}
ctrl[i] = talloc(ctrl, struct ldap_Control);
ctrl[i] = talloc(ctrl, struct ldb_control);
if (!ctrl[i]) {
return False;
}
@ -1348,7 +1348,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg)
return NT_STATUS_OK if a blob has enough bytes in it to be a full
ldap packet. Set packet_size if true.
*/
NTSTATUS ldap_full_packet(void *private, DATA_BLOB blob, size_t *packet_size)
NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size)
{
return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size);
}

View File

@ -240,17 +240,11 @@ union ldap_Request {
struct ldap_ExtendedResponse ExtendedResponse;
};
struct ldap_Control {
const char *oid;
BOOL critical;
void *value;
};
struct ldap_message {
int messageid;
enum ldap_request_tag type;
union ldap_Request r;
struct ldap_Control **controls;
struct ldb_control **controls;
};
#include "libcli/ldap/ldap_proto.h"

View File

@ -90,9 +90,9 @@ static void ldap_connection_dead(struct ldap_connection *conn)
/*
handle packet errors
*/
static void ldap_error_handler(void *private, NTSTATUS status)
static void ldap_error_handler(void *private_data, NTSTATUS status)
{
struct ldap_connection *conn = talloc_get_type(private,
struct ldap_connection *conn = talloc_get_type(private_data,
struct ldap_connection);
ldap_connection_dead(conn);
}
@ -155,14 +155,14 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message
check if a blob is a complete ldap packet
handle wrapper or unwrapped connections
*/
NTSTATUS ldap_complete_packet(void *private, DATA_BLOB blob, size_t *size)
NTSTATUS ldap_complete_packet(void *private_data, DATA_BLOB blob, size_t *size)
{
struct ldap_connection *conn = talloc_get_type(private,
struct ldap_connection *conn = talloc_get_type(private_data,
struct ldap_connection);
if (conn->enable_wrap) {
return packet_full_request_u32(private, blob, size);
return packet_full_request_u32(private_data, blob, size);
}
return ldap_full_packet(private, blob, size);
return ldap_full_packet(private_data, blob, size);
}
/*
@ -234,9 +234,9 @@ static NTSTATUS ldap_decode_wrapped(struct ldap_connection *conn, DATA_BLOB blob
/*
handle ldap recv events
*/
static NTSTATUS ldap_recv_handler(void *private, DATA_BLOB blob)
static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob)
{
struct ldap_connection *conn = talloc_get_type(private,
struct ldap_connection *conn = talloc_get_type(private_data,
struct ldap_connection);
if (conn->enable_wrap) {
return ldap_decode_wrapped(conn, blob);
@ -250,9 +250,9 @@ static NTSTATUS ldap_recv_handler(void *private, DATA_BLOB blob)
handle ldap socket events
*/
static void ldap_io_handler(struct event_context *ev, struct fd_event *fde,
uint16_t flags, void *private)
uint16_t flags, void *private_data)
{
struct ldap_connection *conn = talloc_get_type(private,
struct ldap_connection *conn = talloc_get_type(private_data,
struct ldap_connection);
if (flags & EVENT_FD_WRITE) {
packet_queue_run(conn->packet);
@ -433,9 +433,9 @@ static int ldap_request_destructor(void *ptr)
called on timeout of a ldap request
*/
static void ldap_request_timeout(struct event_context *ev, struct timed_event *te,
struct timeval t, void *private)
struct timeval t, void *private_data)
{
struct ldap_request *req = talloc_get_type(private, struct ldap_request);
struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
req->status = NT_STATUS_IO_TIMEOUT;
if (req->state == LDAP_REQUEST_PENDING) {
DLIST_REMOVE(req->conn->pending, req);
@ -451,9 +451,9 @@ static void ldap_request_timeout(struct event_context *ev, struct timed_event *t
called on completion of a one-way ldap request
*/
static void ldap_request_complete(struct event_context *ev, struct timed_event *te,
struct timeval t, void *private)
struct timeval t, void *private_data)
{
struct ldap_request *req = talloc_get_type(private, struct ldap_request);
struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
if (req->async.fn) {
req->async.fn(req);
}
@ -534,7 +534,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
DLIST_ADD(conn->pending, req);
/* put a timeout on the request */
event_add_timed(conn->event.event_ctx, req,
req->time_event = event_add_timed(conn->event.event_ctx, req,
timeval_current_ofs(conn->timeout, 0),
ldap_request_timeout, req);

View File

@ -42,8 +42,10 @@ struct ldap_request {
DATA_BLOB data;
struct {
void (*fn)(struct ldap_request *);
void *private;
void *private_data;
} async;
struct timed_event *time_event;
};

View File

@ -381,10 +381,14 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
return False;
}
if (asn1_peek_tag(&data, ASN1_SEQUENCE(0))) {
if (asn1_peek_tag(&data, ASN1_CONTEXT(0))) {
lvrc->type = 0;
if (!asn1_start_tag(&data, ASN1_CONTEXT(0))) {
return False;
}
if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
return False;
}
@ -397,7 +401,11 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
return False;
}
if (!asn1_end_tag(&data)) {
if (!asn1_end_tag(&data)) { /*SEQUENCE*/
return False;
}
if (!asn1_end_tag(&data)) { /*CONTEXT*/
return False;
}
@ -405,6 +413,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
lvrc->type = 1;
if (!asn1_start_tag(&data, ASN1_CONTEXT(1))) {
return False;
}
if (!asn1_read_OctetString(&data, &assertion_value)) {
return False;
}
@ -418,6 +430,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
} else {
lvrc->match.gtOrEq.value = NULL;
}
if (!asn1_end_tag(&data)) { /*CONTEXT*/
return False;
}
}
if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) {
@ -755,6 +771,10 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
}
if (lvrc->type == 0) {
if (!asn1_push_tag(&data, ASN1_CONTEXT(0))) {
return False;
}
if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
return False;
}
@ -767,14 +787,25 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
return False;
}
if (!asn1_pop_tag(&data)) {
if (!asn1_pop_tag(&data)) { /*SEQUENCE*/
return False;
}
if (!asn1_pop_tag(&data)) { /*CONTEXT*/
return False;
}
} else {
if (!asn1_push_tag(&data, ASN1_CONTEXT(1))) {
return False;
}
if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) {
return False;
}
if (!asn1_pop_tag(&data)) { /*CONTEXT*/
return False;
}
}
if (lvrc->ctxid_len) {
@ -850,7 +881,7 @@ struct control_handler ldap_known_controls[] = {
{ NULL, NULL, NULL }
};
BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl)
BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl)
{
int i;
DATA_BLOB oid;
@ -876,7 +907,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont
ctrl->critical = False;
}
ctrl->value = NULL;
ctrl->data = NULL;
if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) {
goto end_tag;
@ -888,7 +919,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont
for (i = 0; ldap_known_controls[i].oid != NULL; i++) {
if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) {
if (!ldap_known_controls[i].decode(mem_ctx, value, &ctrl->value)) {
if (!ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) {
return False;
}
break;
@ -906,7 +937,7 @@ end_tag:
return True;
}
BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl)
BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl)
{
DATA_BLOB value;
int i;
@ -925,13 +956,13 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont
}
}
if (!ctrl->value) {
if (!ctrl->data) {
goto pop_tag;
}
for (i = 0; ldap_known_controls[i].oid != NULL; i++) {
if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) {
if (!ldap_known_controls[i].encode(mem_ctx, ctrl->value, &value)) {
if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) {
return False;
}
break;

View File

@ -152,13 +152,13 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res)
/*
perform a ldap search
perform a synchronous ldap search
*/
NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn,
int scope, struct ldb_parse_tree *tree,
const char * const *attrs, BOOL attributesonly,
struct ldap_Control **control_req,
struct ldap_Control ***control_res,
struct ldb_control **control_req,
struct ldb_control ***control_res,
struct ldap_message ***results)
{
struct ldap_message *msg;
@ -203,7 +203,9 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn,
break;
}
if (res->type != LDAP_TAG_SearchResultEntry) continue;
if (res->type != LDAP_TAG_SearchResultEntry &&
res->type != LDAP_TAG_SearchResultReference)
continue;
(*results) = talloc_realloc(conn, *results, struct ldap_message *, n+2);
if (*results == NULL) {
@ -228,8 +230,8 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn,
NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn,
int scope, const char *expression,
const char * const *attrs, BOOL attributesonly,
struct ldap_Control **control_req,
struct ldap_Control ***control_res,
struct ldb_control **control_req,
struct ldb_control ***control_res,
struct ldap_message ***results)
{
struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression);