mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
ncacn_http: DCERPC pipe open using http transport
Signed-off-by: Samuel Cabrero <samuelcabrero@kernevil.me> Reviewed-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
d617230888
commit
594d036afd
@ -403,6 +403,177 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp_recv(struct composite_context *
|
||||
}
|
||||
|
||||
|
||||
struct pipe_http_state {
|
||||
struct dcerpc_pipe_connect io;
|
||||
const char *localaddr;
|
||||
const char *rpc_server;
|
||||
uint32_t rpc_server_port;
|
||||
char *rpc_proxy;
|
||||
uint32_t rpc_proxy_port;
|
||||
char *http_proxy;
|
||||
uint32_t http_proxy_port;
|
||||
bool use_tls;
|
||||
bool use_proxy;
|
||||
bool use_ntlm;
|
||||
struct loadparm_context *lp_ctx;
|
||||
};
|
||||
|
||||
/*
|
||||
Stage 2 of ncacn_http: rpc pipe opened (or not)
|
||||
*/
|
||||
static void continue_pipe_open_ncacn_http(struct tevent_req *subreq)
|
||||
{
|
||||
struct composite_context *c = NULL;
|
||||
struct pipe_http_state *s = NULL;
|
||||
struct tstream_context *stream = NULL;
|
||||
struct tevent_queue *queue = NULL;
|
||||
|
||||
c = tevent_req_callback_data(subreq, struct composite_context);
|
||||
s = talloc_get_type(c->private_data, struct pipe_http_state);
|
||||
|
||||
/* receive result of RoH connect request */
|
||||
c->status = dcerpc_pipe_open_roh_recv(subreq, s->io.conn,
|
||||
&stream, &queue);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!composite_is_ok(c)) return;
|
||||
|
||||
s->io.conn->transport.transport = NCACN_HTTP;
|
||||
s->io.conn->transport.stream = stream;
|
||||
s->io.conn->transport.write_queue = queue;
|
||||
s->io.conn->transport.pending_reads = 0;
|
||||
|
||||
composite_done(c);
|
||||
}
|
||||
|
||||
/*
|
||||
Initiate async open of a rpc connection to a rpc pipe using HTTP transport,
|
||||
and using the binding structure to determine the endpoint and options
|
||||
*/
|
||||
static struct composite_context* dcerpc_pipe_connect_ncacn_http_send(
|
||||
TALLOC_CTX *mem_ctx, struct dcerpc_pipe_connect *io,
|
||||
struct loadparm_context *lp_ctx)
|
||||
{
|
||||
struct composite_context *c;
|
||||
struct pipe_http_state *s;
|
||||
struct tevent_req *subreq;
|
||||
const char *endpoint;
|
||||
const char *use_proxy;
|
||||
char *proxy;
|
||||
char *port;
|
||||
const char *opt;
|
||||
|
||||
/* composite context allocation and setup */
|
||||
c = composite_create(mem_ctx, io->conn->event_ctx);
|
||||
if (c == NULL) return NULL;
|
||||
|
||||
s = talloc_zero(c, struct pipe_http_state);
|
||||
if (composite_nomem(s, c)) return c;
|
||||
c->private_data = s;
|
||||
|
||||
/* store input parameters in state structure */
|
||||
s->lp_ctx = lp_ctx;
|
||||
s->io = *io;
|
||||
s->localaddr = dcerpc_binding_get_string_option(io->binding,
|
||||
"localaddress");
|
||||
/* RPC server and port (the endpoint) */
|
||||
s->rpc_server = dcerpc_binding_get_string_option(io->binding, "host");
|
||||
endpoint = dcerpc_binding_get_string_option(io->binding, "endpoint");
|
||||
if (endpoint == NULL) {
|
||||
composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
|
||||
return c;
|
||||
}
|
||||
s->rpc_server_port = atoi(endpoint);
|
||||
if (s->rpc_server_port == 0) {
|
||||
composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Use TLS */
|
||||
opt = dcerpc_binding_get_string_option(io->binding, "HttpUseTls");
|
||||
if (opt) {
|
||||
if (strcasecmp(opt, "true") == 0) {
|
||||
s->use_tls = true;
|
||||
} else if (strcasecmp(opt, "false") == 0) {
|
||||
s->use_tls = false;
|
||||
} else {
|
||||
composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
|
||||
return c;
|
||||
}
|
||||
} else {
|
||||
s->use_tls = true;
|
||||
}
|
||||
|
||||
/* RPC Proxy */
|
||||
proxy = port = talloc_strdup(s, dcerpc_binding_get_string_option(
|
||||
io->binding, "RpcProxy"));
|
||||
s->rpc_proxy = strsep(&port, ":");
|
||||
if (proxy && port) {
|
||||
s->rpc_proxy_port = atoi(port);
|
||||
} else {
|
||||
s->rpc_proxy_port = s->use_tls ? 443 : 80;
|
||||
}
|
||||
if (s->rpc_proxy == NULL) {
|
||||
s->rpc_proxy = talloc_strdup(s, s->rpc_server);
|
||||
if (composite_nomem(s->rpc_proxy, c)) return c;
|
||||
}
|
||||
|
||||
/* HTTP Proxy */
|
||||
proxy = port = talloc_strdup(s, dcerpc_binding_get_string_option(
|
||||
io->binding, "HttpProxy"));
|
||||
s->http_proxy = strsep(&port, ":");
|
||||
if (proxy && port) {
|
||||
s->http_proxy_port = atoi(port);
|
||||
} else {
|
||||
s->http_proxy_port = s->use_tls ? 443 : 80;
|
||||
}
|
||||
|
||||
/* Use local proxy */
|
||||
use_proxy = dcerpc_binding_get_string_option(io->binding,
|
||||
"HttpConnectOption");
|
||||
if (use_proxy && strcasecmp(use_proxy, "UseHttpProxy")) {
|
||||
s->use_proxy = true;
|
||||
}
|
||||
|
||||
/* If use local proxy set, the http proxy should be provided */
|
||||
if (s->use_proxy && !s->http_proxy) {
|
||||
composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Check which HTTP authentication method to use */
|
||||
opt = dcerpc_binding_get_string_option(io->binding, "HttpAuthOption");
|
||||
if (opt) {
|
||||
if (strcasecmp(opt, "basic") == 0) {
|
||||
s->use_ntlm = false;
|
||||
} else if (strcasecmp(opt, "ntlm") == 0) {
|
||||
s->use_ntlm = true;
|
||||
} else {
|
||||
composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
|
||||
return c;
|
||||
}
|
||||
} else {
|
||||
s->use_ntlm = true;
|
||||
}
|
||||
|
||||
subreq = dcerpc_pipe_open_roh_send(s->io.conn, s->localaddr,
|
||||
s->rpc_server, s->rpc_server_port,
|
||||
s->rpc_proxy, s->rpc_proxy_port,
|
||||
s->http_proxy, s->http_proxy_port,
|
||||
s->use_tls, s->use_proxy,
|
||||
s->io.creds, io->resolve_ctx,
|
||||
s->lp_ctx, s->use_ntlm);
|
||||
if (composite_nomem(subreq, c)) return c;
|
||||
|
||||
tevent_req_set_callback(subreq, continue_pipe_open_ncacn_http, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
static NTSTATUS dcerpc_pipe_connect_ncacn_http_recv(struct composite_context *c)
|
||||
{
|
||||
return composite_wait_free(c);
|
||||
}
|
||||
|
||||
|
||||
struct pipe_unix_state {
|
||||
struct dcerpc_pipe_connect io;
|
||||
const char *path;
|
||||
@ -559,6 +730,7 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st
|
||||
static void continue_pipe_connect_ncacn_np_smb2(struct composite_context *ctx);
|
||||
static void continue_pipe_connect_ncacn_np_smb(struct composite_context *ctx);
|
||||
static void continue_pipe_connect_ncacn_ip_tcp(struct composite_context *ctx);
|
||||
static void continue_pipe_connect_ncacn_http(struct composite_context *ctx);
|
||||
static void continue_pipe_connect_ncacn_unix(struct composite_context *ctx);
|
||||
static void continue_pipe_connect_ncalrpc(struct composite_context *ctx);
|
||||
static void continue_pipe_connect(struct composite_context *c, struct pipe_connect_state *s);
|
||||
@ -597,6 +769,7 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st
|
||||
struct composite_context *ncacn_np_smb2_req;
|
||||
struct composite_context *ncacn_np_smb_req;
|
||||
struct composite_context *ncacn_ip_tcp_req;
|
||||
struct composite_context *ncacn_http_req;
|
||||
struct composite_context *ncacn_unix_req;
|
||||
struct composite_context *ncalrpc_req;
|
||||
enum dcerpc_transport_t transport;
|
||||
@ -635,6 +808,11 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st
|
||||
composite_continue(c, ncacn_ip_tcp_req, continue_pipe_connect_ncacn_ip_tcp, c);
|
||||
return;
|
||||
|
||||
case NCACN_HTTP:
|
||||
ncacn_http_req = dcerpc_pipe_connect_ncacn_http_send(c, &pc, s->lp_ctx);
|
||||
composite_continue(c, ncacn_http_req, continue_pipe_connect_ncacn_http, c);
|
||||
return;
|
||||
|
||||
case NCACN_UNIX_STREAM:
|
||||
ncacn_unix_req = dcerpc_pipe_connect_ncacn_unix_stream_send(c, &pc);
|
||||
composite_continue(c, ncacn_unix_req, continue_pipe_connect_ncacn_unix, c);
|
||||
@ -709,6 +887,23 @@ static void continue_pipe_connect_ncacn_ip_tcp(struct composite_context *ctx)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Stage 3 of pipe_connect_b: Receive result of pipe connect request on http
|
||||
*/
|
||||
static void continue_pipe_connect_ncacn_http(struct composite_context *ctx)
|
||||
{
|
||||
struct composite_context *c = talloc_get_type(ctx->async.private_data,
|
||||
struct composite_context);
|
||||
struct pipe_connect_state *s = talloc_get_type(c->private_data,
|
||||
struct pipe_connect_state);
|
||||
|
||||
c->status = dcerpc_pipe_connect_ncacn_http_recv(ctx);
|
||||
if (!composite_is_ok(c)) return;
|
||||
|
||||
continue_pipe_connect(c, s);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Stage 3 of pipe_connect_b: Receive result of pipe connect request on unix socket
|
||||
*/
|
||||
@ -847,6 +1042,7 @@ _PUBLIC_ struct composite_context* dcerpc_pipe_connect_b_send(TALLOC_CTX *parent
|
||||
switch (transport) {
|
||||
case NCACN_NP:
|
||||
case NCACN_IP_TCP:
|
||||
case NCACN_HTTP:
|
||||
case NCALRPC:
|
||||
endpoint = dcerpc_binding_get_string_option(s->binding, "endpoint");
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user