diff options
author | Stefan Metzmacher <metze@samba.org> | 2017-05-11 16:51:15 +0200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2017-06-15 09:13:22 +0200 |
commit | 900ab851a77ca0cb272fa1a6b0894cac7c41510f (patch) | |
tree | 2a4b00de310417c6117398b1572a8b79951dd39c /source4/ldap_server/ldap_server.c | |
parent | 4c9eeb0d3e26742aa025e86ad677d6dbc3478fcf (diff) | |
download | samba-900ab851a77ca0cb272fa1a6b0894cac7c41510f.tar.gz |
s4:ldap_server: add call->wait_send/recv infrastructure
If it is set by the dispatch functions, the core server
will use call->wait_send() and wait for it to finally
return frim call->wait_recv() before it asks for the
next incoming pdu.
This can be used to implement bind as async operations.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source4/ldap_server/ldap_server.c')
-rw-r--r-- | source4/ldap_server/ldap_server.c | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index 062c3fc4b56..6a6053206b2 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -578,7 +578,8 @@ static void ldapsrv_call_read_done(struct tevent_req *subreq) conn->active_call = subreq; } - +static void ldapsrv_call_wait_done(struct tevent_req *subreq); +static void ldapsrv_call_writev_start(struct ldapsrv_call *call); static void ldapsrv_call_writev_done(struct tevent_req *subreq); static void ldapsrv_call_process_done(struct tevent_req *subreq) @@ -588,7 +589,6 @@ static void ldapsrv_call_process_done(struct tevent_req *subreq) struct ldapsrv_call); struct ldapsrv_connection *conn = call->conn; NTSTATUS status; - DATA_BLOB blob = data_blob_null; conn->active_call = NULL; @@ -599,6 +599,61 @@ static void ldapsrv_call_process_done(struct tevent_req *subreq) return; } + if (call->wait_send != NULL) { + subreq = call->wait_send(call, + conn->connection->event.ctx, + call->wait_private); + if (subreq == NULL) { + ldapsrv_terminate_connection(conn, + "ldapsrv_call_process_done: " + "call->wait_send - no memory"); + return; + } + tevent_req_set_callback(subreq, + ldapsrv_call_wait_done, + call); + conn->active_call = subreq; + return; + } + + ldapsrv_call_writev_start(call); +} + +static void ldapsrv_call_wait_done(struct tevent_req *subreq) +{ + struct ldapsrv_call *call = + tevent_req_callback_data(subreq, + struct ldapsrv_call); + struct ldapsrv_connection *conn = call->conn; + NTSTATUS status; + + conn->active_call = NULL; + + status = call->wait_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + const char *reason; + + reason = talloc_asprintf(call, "ldapsrv_call_wait_done: " + "call->wait_recv() - %s", + nt_errstr(status)); + if (reason == NULL) { + reason = nt_errstr(status); + } + + ldapsrv_terminate_connection(conn, reason); + return; + } + + ldapsrv_call_writev_start(call); +} + +static void ldapsrv_call_writev_start(struct ldapsrv_call *call) +{ + struct ldapsrv_connection *conn = call->conn; + DATA_BLOB blob = data_blob_null; + struct tevent_req *subreq = NULL; + /* build all the replies into a single blob */ while (call->replies) { DATA_BLOB b; |