summaryrefslogtreecommitdiff
path: root/source3/winbindd/winbindd_dual_ndr.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-08-24 00:13:02 +0200
committerVolker Lendecke <vl@samba.org>2009-08-27 15:04:09 +0200
commitf3d71d3e8c1e9c98df38ef5f8c547ff2780e9cfb (patch)
treeded7ed669abc08a5329f21edc9a879a42ae1d45d /source3/winbindd/winbindd_dual_ndr.c
parent3532c8b9d831c8122de871db62d17608ff24f409 (diff)
downloadsamba-f3d71d3e8c1e9c98df38ef5f8c547ff2780e9cfb.tar.gz
samba-f3d71d3e8c1e9c98df38ef5f8c547ff2780e9cfb.tar.bz2
samba-f3d71d3e8c1e9c98df38ef5f8c547ff2780e9cfb.zip
s3:winbind: Add a generic cache for NDR based parent-child requests
Diffstat (limited to 'source3/winbindd/winbindd_dual_ndr.c')
-rw-r--r--source3/winbindd/winbindd_dual_ndr.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/source3/winbindd/winbindd_dual_ndr.c b/source3/winbindd/winbindd_dual_ndr.c
index e6f3265bd5..8a23ce48e0 100644
--- a/source3/winbindd/winbindd_dual_ndr.c
+++ b/source3/winbindd/winbindd_dual_ndr.c
@@ -32,13 +32,16 @@
#include "librpc/gen_ndr/srv_wbint.h"
struct wb_ndr_transport_priv {
+ struct winbindd_domain *domain;
struct winbindd_child *child;
};
struct wb_ndr_dispatch_state {
+ struct wb_ndr_transport_priv *transport;
+ uint32_t opnum;
const struct ndr_interface_call *call;
void *r;
- struct ndr_push *push;
+ DATA_BLOB req_blob, resp_blob;
struct winbindd_request request;
struct winbindd_response *response;
};
@@ -56,7 +59,7 @@ static struct tevent_req *wb_ndr_dispatch_send(TALLOC_CTX *mem_ctx,
struct wb_ndr_dispatch_state *state;
struct wb_ndr_transport_priv *transport = talloc_get_type_abort(
cli->transport->priv, struct wb_ndr_transport_priv);
- DATA_BLOB blob;
+ struct ndr_push *push;
enum ndr_err_code ndr_err;
req = tevent_req_create(mem_ctx, &state,
@@ -67,25 +70,34 @@ static struct tevent_req *wb_ndr_dispatch_send(TALLOC_CTX *mem_ctx,
state->r = r;
state->call = &table->calls[opnum];
+ state->transport = transport;
+ state->opnum = opnum;
- state->push = ndr_push_init_ctx(state, NULL);
- if (tevent_req_nomem(state->push, req)) {
+ push = ndr_push_init_ctx(state, NULL);
+ if (tevent_req_nomem(push, req)) {
return tevent_req_post(req, ev);
}
- ndr_err = state->call->ndr_push(state->push, NDR_IN, r);
+ ndr_err = state->call->ndr_push(push, NDR_IN, r);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
tevent_req_nterror(req, ndr_map_error2ntstatus(ndr_err));
- TALLOC_FREE(state->push);
+ TALLOC_FREE(push);
return tevent_req_post(req, ev);
}
- blob = ndr_push_blob(state->push);
+ state->req_blob = ndr_push_blob(push);
+
+ if ((transport->domain != NULL)
+ && wcache_fetch_ndr(state, transport->domain, opnum,
+ &state->req_blob, &state->resp_blob)) {
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+ }
state->request.cmd = WINBINDD_DUAL_NDRCMD;
state->request.data.ndrcmd = opnum;
- state->request.extra_data.data = (char *)blob.data;
- state->request.extra_len = blob.length;
+ state->request.extra_data.data = (char *)state->req_blob.data;
+ state->request.extra_len = state->req_blob.length;
subreq = wb_child_request_send(state, ev, transport->child,
&state->request);
@@ -110,6 +122,16 @@ static void wb_ndr_dispatch_done(struct tevent_req *subreq)
tevent_req_nterror(req, map_nt_error_from_unix(err));
return;
}
+
+ state->resp_blob = data_blob_const(
+ state->response->extra_data.data,
+ state->response->length - sizeof(struct winbindd_response));
+
+ if (state->transport->domain != NULL) {
+ wcache_store_ndr(state->transport->domain, state->opnum,
+ &state->req_blob, &state->resp_blob);
+ }
+
tevent_req_done(req);
}
@@ -121,17 +143,12 @@ static NTSTATUS wb_ndr_dispatch_recv(struct tevent_req *req,
NTSTATUS status;
struct ndr_pull *pull;
enum ndr_err_code ndr_err;
- DATA_BLOB blob;
if (tevent_req_is_nterror(req, &status)) {
return status;
}
- blob.data = (uint8_t *)state->response->extra_data.data;
- blob.length = state->response->length
- - sizeof(struct winbindd_response);
-
- pull = ndr_pull_init_blob(&blob, mem_ctx, NULL);
+ pull = ndr_pull_init_blob(&state->resp_blob, mem_ctx, NULL);
if (pull == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -182,6 +199,7 @@ static NTSTATUS wb_ndr_dispatch(struct rpc_pipe_client *cli,
}
struct rpc_pipe_client *wbint_rpccli_create(TALLOC_CTX *mem_ctx,
+ struct winbindd_domain *domain,
struct winbindd_child *child)
{
struct rpc_pipe_client *result;
@@ -220,6 +238,7 @@ struct rpc_pipe_client *wbint_rpccli_create(TALLOC_CTX *mem_ctx,
TALLOC_FREE(result);
return NULL;
}
+ transp->domain = domain;
transp->child = child;
result->transport->priv = transp;
return result;