diff options
author | Stefan Metzmacher <metze@samba.org> | 2018-11-21 19:19:15 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2019-01-12 03:13:39 +0100 |
commit | a8134191ec000b236948b93d2e2290cc4dc8b110 (patch) | |
tree | 3d0790c6d49cf2465ab8a2780d111b96c6d73ad9 /source4 | |
parent | 199d4ba7ac45d2740987be0b85438d2b4c532035 (diff) | |
download | samba-a8134191ec000b236948b93d2e2290cc4dc8b110.tar.gz |
s4:rpc_server/remote: defer the connect to the first client request
This means we have a chance to use delegated credentials from the client
if available, as the authentication is already completed.
Before we only ever used the transport inherited credentials
via SMB or anonymous.
Note: most times we still fallback to anonymous...
BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4')
-rw-r--r-- | source4/rpc_server/remote/dcesrv_remote.c | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 9e40a974e0c..7a1ec3f78f9 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -41,10 +41,17 @@ static NTSTATUS remote_op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX * static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) { - NTSTATUS status; + dce_call->context->private_data = NULL; + return NT_STATUS_OK; +} + +static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, + struct dcesrv_remote_private **_priv) +{ const struct ndr_interface_table *table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; - struct dcesrv_remote_private *priv; + void *ptr = NULL; + struct dcesrv_remote_private *priv = NULL; const char *binding = NULL; const char *user, *pass, *domain; struct cli_credentials *credentials; @@ -54,14 +61,20 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct struct dcerpc_binding *b; struct composite_context *pipe_conn_req; uint32_t flags = 0; + NTSTATUS status; - priv = talloc(dce_call->conn, struct dcesrv_remote_private); - if (!priv) { - return NT_STATUS_NO_MEMORY; + ptr = dce_call->context->private_data; + if (ptr != NULL) { + priv = talloc_get_type_abort(ptr, struct dcesrv_remote_private); + + *_priv = priv; + return NT_STATUS_OK; + } + + priv = talloc_zero(dce_call, struct dcesrv_remote_private); + if (priv == NULL) { + return NT_STATUS_NO_MEMORY; } - - priv->c_pipe = NULL; - dce_call->context->private_data = priv; binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, @@ -132,7 +145,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct } /* parse binding string to the structure */ - status = dcerpc_parse_binding(dce_call->context, binding, &b); + status = dcerpc_parse_binding(priv, binding, &b); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", binding)); return status; @@ -156,7 +169,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - if (dce_call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) { + if (dce_call->conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED) { status = dcerpc_binding_set_flags(b, DCERPC_CONCURRENT_MULTIPLEX, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dcerpc_binding_set_flags(CONC_MPX) - %s'\n", @@ -167,9 +180,9 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b))); - pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table, + pipe_conn_req = dcerpc_pipe_connect_b_send(priv, b, table, credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); - status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(priv->c_pipe)); + status = dcerpc_pipe_connect_b_recv(pipe_conn_req, priv, &(priv->c_pipe)); if (must_free_credentials) { talloc_free(credentials); @@ -179,7 +192,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - if (dce_call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) { + if (dce_call->conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED) { flags = dcerpc_binding_get_flags(priv->c_pipe->binding); if (!(flags & DCERPC_CONCURRENT_MULTIPLEX)) { DEBUG(1,("dcerpc_remote: RPC Proxy: " @@ -197,17 +210,8 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct return status; } - return NT_STATUS_OK; -} - -static NTSTATUS remote_get_private(struct dcesrv_call_state *dce_call, - struct dcesrv_remote_private **_priv) -{ - void *ptr = NULL; - struct dcesrv_remote_private *priv = NULL; - - ptr = dce_call->context->private_data; - priv = talloc_get_type_abort(ptr, struct dcesrv_remote_private); + dce_call->context->private_data = priv; + talloc_reparent(dce_call, dce_call->conn, priv); *_priv = priv; return NT_STATUS_OK; @@ -268,14 +272,15 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT struct tevent_req *subreq; NTSTATUS status; + name = table->calls[opnum].name; + call = &table->calls[opnum]; + status = remote_get_private(dce_call, &priv); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("dcesrv_remote: call[%s] %s\n", name, nt_errstr(status))); return status; } - name = table->calls[opnum].name; - call = &table->calls[opnum]; - if (priv->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_IN) { ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r); } |