Add an async wb request loop
authorVolker Lendecke <vl@samba.org>
Sat, 16 May 2009 10:00:07 +0000 (12:00 +0200)
committerVolker Lendecke <vl@samba.org>
Sun, 14 Jun 2009 09:25:47 +0000 (11:25 +0200)
source3/winbindd/winbindd.c
source3/winbindd/winbindd.h

index 31ab48f4ffe6c677cf3331734825354f7de814a3..d4d54e31f62c670d046afb6099681e44411c4f8c 100644 (file)
@@ -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.
index 7b71502999689c093fb5cbf5f3db12ff28689809..ae688e251c078ac03507c37194f7e6efeb454116 100644 (file)
@@ -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;