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

s4:libcli/ldap: send AbandonRequests for cancelled requests

This happens on a local timeout of an talloc_free() of the request.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Stefan Metzmacher 2016-02-01 11:00:14 +01:00 committed by Garming Sam
parent a077e2ae62
commit cd77b0bba4

View File

@ -662,13 +662,48 @@ static void ldap_reconnect(struct ldap_connection *conn)
}
}
static void ldap_request_destructor_abandon(struct ldap_request *abandon)
{
TALLOC_FREE(abandon);
}
/* destroy an open ldap request */
static int ldap_request_destructor(struct ldap_request *req)
{
if (req->state == LDAP_REQUEST_PENDING) {
struct ldap_message msg = {
.type = LDAP_TAG_AbandonRequest,
.r.AbandonRequest.messageid = req->messageid,
};
struct ldap_request *abandon = NULL;
DLIST_REMOVE(req->conn->pending, req);
abandon = ldap_request_send(req->conn, &msg);
if (abandon == NULL) {
ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY);
return 0;
}
abandon->async.fn = ldap_request_destructor_abandon;
abandon->async.private_data = NULL;
}
return 0;
}
static void ldap_request_timeout_abandon(struct ldap_request *abandon)
{
struct ldap_request *req =
talloc_get_type_abort(abandon->async.private_data,
struct ldap_request);
if (req->state == LDAP_REQUEST_PENDING) {
DLIST_REMOVE(req->conn->pending, req);
}
return 0;
req->state = LDAP_REQUEST_DONE;
if (req->async.fn) {
req->async.fn(req);
}
}
/*
@ -683,7 +718,22 @@ static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer
req->status = NT_STATUS_IO_TIMEOUT;
if (req->state == LDAP_REQUEST_PENDING) {
struct ldap_message msg = {
.type = LDAP_TAG_AbandonRequest,
.r.AbandonRequest.messageid = req->messageid,
};
struct ldap_request *abandon = NULL;
abandon = ldap_request_send(req->conn, &msg);
if (abandon == NULL) {
ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY);
return;
}
talloc_reparent(req->conn, req, abandon);
abandon->async.fn = ldap_request_timeout_abandon;
abandon->async.private_data = req;
DLIST_REMOVE(req->conn->pending, req);
return;
}
req->state = LDAP_REQUEST_DONE;
if (req->async.fn) {