#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;
};
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,
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);
+ 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);
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);
}
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);
if (pull == NULL) {
return NT_STATUS_NO_MEMORY;
}
}
struct rpc_pipe_client *wbint_rpccli_create(TALLOC_CTX *mem_ctx,
+ struct winbindd_domain *domain,
struct winbindd_child *child)
{
struct rpc_pipe_client *result;
TALLOC_FREE(result);
return NULL;
}
+ transp->domain = domain;
transp->child = child;
result->transport->priv = transp;
return result;
return WINBINDD_ERROR;
}
+ DEBUG(10, ("winbindd_dual_ndrcmd: Running command %s (%s)\n",
+ fns[state->request->data.ndrcmd].name,
+ domain ? domain->name : "no domain"));
+
ZERO_STRUCT(p);
p.mem_ctx = talloc_stackframe();
p.in_data.data.buffer_size = state->request->extra_len;