s3-rpc: make api_rpcTNP async
authorDavid Disseldorp <ddiss@samba.org>
Thu, 26 Apr 2012 11:26:04 +0000 (13:26 +0200)
committerDavid Disseldorp <ddiss@samba.org>
Wed, 19 Sep 2012 03:59:02 +0000 (05:59 +0200)
source3/rpc_server/srv_pipe.c

index 0eb51b568f820591721c1e5caef47f0914e05ece..79c616baee8eb6fce0c9075ce153b3e9a8e222bc 100644 (file)
@@ -1282,13 +1282,18 @@ static bool api_pipe_alter_context(struct pipes_struct *p,
        return setup_bind_nak(p, pkt);
 }
 
-static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
-                      const struct api_struct *api_rpc_cmds, int n_cmds,
-                      const struct ndr_syntax_id *syntax);
+static struct tevent_req *api_rpcTNP_send(struct tevent_context *ev,
+                                         struct pipes_struct *p,
+                                         struct ncacn_packet *pkt,
+                                         const struct api_struct *api_rpc_cmds,
+                                         int n_cmds,
+                                         const struct ndr_syntax_id *syntax);
+static bool api_rpcTNP_recv(struct tevent_req *req);
 
 struct api_pipe_request_state {
        bool ret;
 };
+static void api_pipe_request_done(struct tevent_req *subreq);
 /****************************************************************************
  Find the correct RPC function to call for this request.
  If the pipe is authenticated then become the correct UNIX user
@@ -1327,16 +1332,23 @@ static struct tevent_req *api_pipe_request_send(struct tevent_context *ev,
        pipe_fns = find_pipe_fns_by_context(p->contexts,
                                            pkt->u.request.context_id);
 
-       if ( pipe_fns ) {
+       if (pipe_fns) {
+               struct tevent_req *subreq;
                TALLOC_CTX *frame = talloc_stackframe();
 
                DEBUG(5, ("Requested %s rpc service\n",
                          get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
 
-               state->ret = api_rpcTNP(p, pkt, pipe_fns->cmds,
-                                       pipe_fns->n_cmds,
-                                       &pipe_fns->syntax);
+               subreq = api_rpcTNP_send(ev, p, pkt, pipe_fns->cmds,
+                                        pipe_fns->n_cmds,
+                                        &pipe_fns->syntax);
                TALLOC_FREE(frame);
+               unbecome_authenticated_pipe_user();
+               if (tevent_req_nomem(subreq, req)) {
+                       return tevent_req_post(req, ev);
+               }
+               tevent_req_set_callback(subreq, api_pipe_request_done, req);
+               return req;
        }
        else {
                DEBUG(0, ("No rpc function table associated with context "
@@ -1349,6 +1361,17 @@ static struct tevent_req *api_pipe_request_send(struct tevent_context *ev,
        return tevent_req_post(req, ev);
 }
 
+static void api_pipe_request_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                                         struct tevent_req);
+       struct api_pipe_request_state *state
+               = tevent_req_data(req, struct api_pipe_request_state);
+
+       state->ret = api_rpcTNP_recv(subreq);
+       tevent_req_done(req);
+}
+
 static bool api_pipe_request_recv(struct tevent_req *req)
 {
        struct api_pipe_request_state *state
@@ -1360,16 +1383,28 @@ static bool api_pipe_request_recv(struct tevent_req *req)
 }
 
 
+struct api_rpcTNP_state {
+       bool ret;
+};
 /*******************************************************************
  Calls the underlying RPC function for a named pipe.
  ********************************************************************/
 
-static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
-                      const struct api_struct *api_rpc_cmds, int n_cmds,
-                      const struct ndr_syntax_id *syntax)
+static struct tevent_req *api_rpcTNP_send(struct tevent_context *ev,
+                                         struct pipes_struct *p,
+                                         struct ncacn_packet *pkt,
+                                         const struct api_struct *api_rpc_cmds,
+                                         int n_cmds,
+                                         const struct ndr_syntax_id *syntax)
 {
        int fn_num;
        uint32_t offset1;
+       struct api_rpcTNP_state *state;
+       struct tevent_req *req = tevent_req_create(p->mem_ctx, &state,
+                                                  struct api_rpcTNP_state);
+       if (req == NULL) {
+               return NULL;
+       }
 
        /* interpret the command */
        DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
@@ -1402,7 +1437,9 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
                 */
                DEBUG(4, ("unknown\n"));
                setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
-               return True;
+               state->ret = true;
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
        }
 
        offset1 = p->out_data.rdata.length;
@@ -1415,14 +1452,18 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
                         get_pipe_name_from_syntax(talloc_tos(), syntax),
                         api_rpc_cmds[fn_num].name));
                data_blob_free(&p->out_data.rdata);
-               return False;
+               state->ret = false;
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
        }
 
        if (p->fault_state) {
                DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
                setup_fault_pdu(p, NT_STATUS(p->fault_state));
                p->fault_state = 0;
-               return true;
+               state->ret = true;
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
        }
 
        if (DEBUGLEVEL >= 50) {
@@ -1445,9 +1486,22 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
                              p->in_data.data.length - pkt->frag_length);
        }
 
-       return True;
+       state->ret = true;
+       tevent_req_done(req);
+       return tevent_req_post(req, ev);
 }
 
+static bool api_rpcTNP_recv(struct tevent_req *req)
+{
+       struct api_rpcTNP_state *state
+               = tevent_req_data(req, struct api_rpcTNP_state);
+       bool ret = state->ret;
+
+       tevent_req_received(req);
+       return ret;
+}
+
+
 /****************************************************************************
  Initialise an outgoing packet.
 ****************************************************************************/