summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/winbindd/winbindd.c61
-rw-r--r--source3/winbindd/winbindd.h2
2 files changed, 63 insertions, 0 deletions
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 31ab48f4ff..d4d54e31f6 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -505,9 +505,26 @@ static struct winbindd_dispatch_table {
{ WINBINDD_NUM_CMDS, NULL, "NONE" }
};
+struct winbindd_async_dispatch_table {
+ enum winbindd_cmd cmd;
+ const char *cmd_name;
+ struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct winbindd_request *request);
+ NTSTATUS (*recv_req)(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ struct winbindd_response **presp);
+};
+
+static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
+ { 0, NULL, NULL, NULL }
+};
+
+static void wb_request_done(struct tevent_req *req);
+
static void process_request(struct winbindd_cli_state *state)
{
struct winbindd_dispatch_table *table = dispatch_table;
+ struct winbindd_async_dispatch_table *atable;
ZERO_STRUCT(state->response);
@@ -523,6 +540,31 @@ static void process_request(struct winbindd_cli_state *state)
/* Process command */
+ for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
+ if (state->request->cmd == atable->cmd) {
+ break;
+ }
+ }
+
+ if (atable->send_req != NULL) {
+ struct tevent_req *req;
+
+ DEBUG(10, ("process_request: Handling async request %s\n",
+ atable->cmd_name));
+
+ req = atable->send_req(state->mem_ctx, winbind_event_context(),
+ state->request);
+ if (req == NULL) {
+ DEBUG(0, ("process_request: atable->send failed for "
+ "%s\n", atable->cmd_name));
+ request_error(state);
+ return;
+ }
+ tevent_req_set_callback(req, wb_request_done, state);
+ state->recv_fn = atable->recv_req;
+ return;
+ }
+
for (table = dispatch_table; table->fn; table++) {
if (state->request->cmd == table->cmd) {
DEBUG(10,("process_request: request fn %s\n",
@@ -539,6 +581,25 @@ static void process_request(struct winbindd_cli_state *state)
}
}
+static void wb_request_done(struct tevent_req *req)
+{
+ struct winbindd_cli_state *state = tevent_req_callback_data(
+ req, struct winbindd_cli_state);
+ NTSTATUS status;
+ struct winbindd_response *response;
+
+ status = state->recv_fn(req, state->mem_ctx, &response);
+ TALLOC_FREE(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("returning %s\n", nt_errstr(status)));
+ request_error(state);
+ }
+ state->response = *response;
+ state->response.result = WINBINDD_PENDING;
+ state->response.length = sizeof(struct winbindd_response);
+ request_ok(state);
+}
+
/*
* This is the main event loop of winbind requests. It goes through a
* state-machine of 3 read/write requests, 4 if you have extra data to send.
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 7b71502999..ae688e251c 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -57,6 +57,8 @@ struct winbindd_cli_state {
bool privileged; /* Is the client 'privileged' */
TALLOC_CTX *mem_ctx; /* memory per request */
+ NTSTATUS (*recv_fn)(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ struct winbindd_response **presp);
struct winbindd_request *request; /* Request from client */
struct winbindd_request _request;
struct tevent_queue *out_queue;