summaryrefslogtreecommitdiff
path: root/source4/ldap_server
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2017-05-11 16:51:15 +0200
committerAndrew Bartlett <abartlet@samba.org>2017-06-15 09:13:22 +0200
commit900ab851a77ca0cb272fa1a6b0894cac7c41510f (patch)
tree2a4b00de310417c6117398b1572a8b79951dd39c /source4/ldap_server
parent4c9eeb0d3e26742aa025e86ad677d6dbc3478fcf (diff)
downloadsamba-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')
-rw-r--r--source4/ldap_server/ldap_server.c59
-rw-r--r--source4/ldap_server/ldap_server.h6
2 files changed, 63 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;
diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h
index 337c974aaae..d3e31fb1eec 100644
--- a/source4/ldap_server/ldap_server.h
+++ b/source4/ldap_server/ldap_server.h
@@ -73,6 +73,12 @@ struct ldapsrv_call {
} *replies;
struct iovec out_iov;
+ struct tevent_req *(*wait_send)(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ void *private_data);
+ NTSTATUS (*wait_recv)(struct tevent_req *req);
+ void *wait_private;
+
struct tevent_req *(*postprocess_send)(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
void *private_data);