The branch, master has been updated via 5e892fb s4-dns: dlz_bind9: improve log message consistency via f15d10d s4-dns: dlz_bind9: Fix ipv6 updates via 13b36be s4:librpc/rpc: allow a shortcut in dcerpc_pipe_connect_ncacn_np_smb[2]_send() via a13eeba s4:librpc/rpc: split out continue_smb_open() via 35192e8 s4:librpc/rpc: remove pipe_np_smb2_state and use pipe_np_smb_state via 7ea0475 s4:librpc/rpc: remember some smbXcli_* pointers within struct dcerpc_pipe_connect via ae406ac s4:librpc/rpc: use DCERPC_REQUEST_TIMEOUT for smb opens via d1b5016 s4:librpc/rpc: remove some unused functions and structures from dcerpc_sock.c via e4f7b90 s4:librpc/rpc: avoid using dcerpc_socket_peer_addr() via 3aebaf4 s4:librpc/rpc: set "localaddress" and reset "host" for ncacn_ip_tcp via 374c5c4 s4:librpc/rpc: return the local/remote ip from dcerpc_pipe_open_tcp_recv() via 4c11fa6 s4:librpc/rpc: optionally return the local address from dcerpc_pipe_open_socket_recv() via dfee057 s4:librpc/rpc: avoid using dcerpc_unix_socket_path() from a448699 torture3: Add a little gencache_parse load test
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 5e892fb674c13e5a3b35b310557d1e2a43bd5bb5 Author: Arvid Requate <requ...@univention.de> Date: Sun May 18 19:16:06 2014 +0200 s4-dns: dlz_bind9: improve log message consistency Change-Id: I0a12c048fd4e667b9aa0777f99c8f8306fc090ea Signed-off-by: Arvid Requate <requ...@univention.de> Reviewed-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Kai Blin <k...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Mon May 26 05:55:46 CEST 2014 on sn-devel-104 commit f15d10df29285024eae75eb83e03ff14d22524e6 Author: Arvid Requate <requ...@univention.de> Date: Sat May 17 18:25:01 2014 +0200 s4-dns: dlz_bind9: Fix ipv6 updates b9_record_match needs to consider all allowed representations of IPv6 addresses (RFC 2373), otherwise DNS subtractrdataset operations fail due to differences in zero padding between bind9 frontend and ndr_pull of a dnsp_DnssrvRpcRecord structure. Change-Id: Ic0a1b16008458993dc644646d7f4ae3d3a3c5fed Signed-off-by: Arvid Requate <requ...@univention.de> Reviewed-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Kai Blin <k...@samba.org> Reviewed-by: Guenter Kukkukk <ku...@samba.org> commit 13b36be68fb54d8e993aefe7b8b5e53f7316a126 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 15 13:06:20 2014 +0100 s4:librpc/rpc: allow a shortcut in dcerpc_pipe_connect_ncacn_np_smb[2]_send() If the caller provided smbXcli * pointers of an existing connection, we can use it. This will be used later in order to allow multiple dcerpc connections over the same smb connection. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit a13eebac7dbc4c496e3784d2b31be89670dddb6d Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 15 13:03:27 2014 +0100 s4:librpc/rpc: split out continue_smb_open() The smb and smb2 code pathes are the same. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 35192e8316291daf70576ceeb483c0204ec9d455 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 15 12:58:52 2014 +0100 s4:librpc/rpc: remove pipe_np_smb2_state and use pipe_np_smb_state There's no need for two almost identical structures. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 7ea04759d7f94a5d4fa57a63612afd9e752ba5e9 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 15 12:56:36 2014 +0100 s4:librpc/rpc: remember some smbXcli_* pointers within struct dcerpc_pipe_connect This will simplify further improvements. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ae406ac6687a5c093e196741ac0187cf27a83b3d Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 15 13:17:42 2014 +0100 s4:librpc/rpc: use DCERPC_REQUEST_TIMEOUT for smb opens There's no need to make the connect timeout dynamic. We implicitly used SMB_REQUEST_TIMEOUT which is also 60 seconds before. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit d1b5016572a3d1fe45a50015bcaf7ecb51ed6a4d Author: Stefan Metzmacher <me...@samba.org> Date: Fri Feb 14 01:15:23 2014 +0100 s4:librpc/rpc: remove some unused functions and structures from dcerpc_sock.c Now we just dcerpc_sock.c doesn't need to maintain 'struct sock_private' in p->transport.private_data anymore, we're just using a raw tstream_context as p->transport.stream. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit e4f7b90295c461da8acdf1c4f23ae02c00211ed1 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Feb 14 01:08:31 2014 +0100 s4:librpc/rpc: avoid using dcerpc_socket_peer_addr() We use information stored in the dcerpc_binding in order to open a secondary connection. The goals are: - dcerpc_secondary_connection_* should just use the dcerpc_binding information for the first connection and just call dcerpc_pipe_connect_* - Get rid of dcerpc_pipe->transport.* and just use a tstream_context. All other details should be maintained only by the higher levels. - Hide dcerpc_pipe and dcecli_connection behind dcerpc_binding_handle. - Have just one entry point to create a new connection. For source4/librpc this will be dcerpc_pipe_connect_*. For source3/rpc_client we need a similar function. - We'll have a new dcerpc_connection layer, with also just one entry point to create a new connection. - Replace dcerpc_pipe and dcecli_connection with the new dcerpc_connection layer. - Replace rpc_pipe_client with the new dcerpc_connection layer. - When the client side is unified we can change the server as it needs to act as a client in order to register the endpoint mappings. - Then the core of the server will be changed to use the new dcerpc_connection layer. As dcerpc_socket_peer_addr() uses p->transport.private_data as 'struct sock_private', we should avoid it. We can then remove dcerpc_unix_socket_path() and 'struct sock_private'. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 3aebaf4c1340292baec0db8448e60af2079600c1 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Feb 13 16:28:54 2014 +0100 s4:librpc/rpc: set "localaddress" and reset "host" for ncacn_ip_tcp We should remember local and remote ip address in dcerpc_pipe->binding. Note: that we still have the "target_hostname" unmodified, if present. This way dcerpc_pipe->binding can be used to create a secondary connection that is a additional connection for the existing association group. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 374c5c4109facbcf3e9a20d1b116d369f14164c0 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Feb 13 16:27:22 2014 +0100 s4:librpc/rpc: return the local/remote ip from dcerpc_pipe_open_tcp_recv() It's important that the caller can remember the ips, so that a secondary connection can use the same addresses in order to get association group binding to work. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 4c11fa68d48caa06d6f9c9db462a2d2e6a0bc3d3 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Feb 13 16:22:59 2014 +0100 s4:librpc/rpc: optionally return the local address from dcerpc_pipe_open_socket_recv() The caller should be able to remember the local address that was used for the connection. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit dfee05744797459d1303a54edb5955dec1e4cb1a Author: Stefan Metzmacher <me...@samba.org> Date: Thu Feb 13 09:53:49 2014 +0100 s4:librpc/rpc: avoid using dcerpc_unix_socket_path() We use information stored in the dcerpc_binding in order to open a secondary connection. The goals are: - dcerpc_secondary_connection_* should just use the dcerpc_binding information for the first connection and just call dcerpc_pipe_connect_* - Get rid of dcerpc_pipe->transport.* and just use a tstream_context. All other details should be maintained only by the higher levels. - Hide dcerpc_pipe and dcecli_connection behind dcerpc_binding_handle. - Have just one entry point to create a new connection. For source4/librpc this will be dcerpc_pipe_connect_*. For source3/rpc_client we need a similar function. - We'll have a new dcerpc_connection layer, with also just one entry point to create a new connection. - Replace dcerpc_pipe and dcecli_connection with the new dcerpc_connection layer. - Replace rpc_pipe_client with the new dcerpc_connection layer. - When the client side is unified we can change the server as it needs to act as a client in order to register the endpoint mappings. - Then the core of the server will be changed to use the new dcerpc_connection layer. As dcerpc_unix_socket_path() uses p->transport.private_data as 'struct sock_private', we should avoid it. We can then remove dcerpc_unix_socket_path() and 'struct sock_private'. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: source4/dns_server/dlz_bind9.c | 14 ++- source4/librpc/rpc/dcerpc_connect.c | 137 +++++++++++++++----------------- source4/librpc/rpc/dcerpc_secondary.c | 123 +++++++++++++++++++++++++----- source4/librpc/rpc/dcerpc_smb.c | 12 +-- source4/librpc/rpc/dcerpc_sock.c | 100 ++++++++++++------------ 5 files changed, 231 insertions(+), 155 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index 677578a..3ffb06b 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -210,7 +210,7 @@ static bool b9_format(struct dlz_bind9_data *state, } default: - state->log(ISC_LOG_ERROR, "samba b9_putrr: unhandled record type %u", + state->log(ISC_LOG_ERROR, "samba_dlz b9_format: unhandled record type %u", rec->wType); return false; } @@ -379,14 +379,14 @@ static bool b9_parse(struct dlz_bind9_data *state, break; default: - state->log(ISC_LOG_ERROR, "samba b9_parse: unhandled record type %u", + state->log(ISC_LOG_ERROR, "samba_dlz b9_parse: unhandled record type %u", rec->wType); return false; } /* we should be at the end of the buffer now */ if (strtok_r(NULL, "\t ", &saveptr) != NULL) { - state->log(ISC_LOG_ERROR, "samba b9_parse: unexpected data at end of string for '%s'", + state->log(ISC_LOG_ERROR, "samba_dlz b9_parse: unexpected data at end of string for '%s'", rdatastr); return false; } @@ -1440,6 +1440,8 @@ static bool b9_record_match(struct dlz_bind9_data *state, { bool status; int i; + struct in6_addr rec1_in_addr6; + struct in6_addr rec2_in_addr6; if (rec1->wType != rec2->wType) { return false; @@ -1454,7 +1456,9 @@ static bool b9_record_match(struct dlz_bind9_data *state, case DNS_TYPE_A: return strcmp(rec1->data.ipv4, rec2->data.ipv4) == 0; case DNS_TYPE_AAAA: - return strcmp(rec1->data.ipv6, rec2->data.ipv6) == 0; + inet_pton(AF_INET6, rec1->data.ipv6, &rec1_in_addr6); + inet_pton(AF_INET6, rec2->data.ipv6, &rec2_in_addr6); + return memcmp(&rec1_in_addr6, &rec2_in_addr6, sizeof(rec1_in_addr6)) == 0; case DNS_TYPE_CNAME: return dns_name_equal(rec1->data.cname, rec2->data.cname); case DNS_TYPE_TXT: @@ -1492,7 +1496,7 @@ static bool b9_record_match(struct dlz_bind9_data *state, rec1->data.soa.expire == rec2->data.soa.expire && rec1->data.soa.minimum == rec2->data.soa.minimum; default: - state->log(ISC_LOG_ERROR, "samba b9_putrr: unhandled record type %u", + state->log(ISC_LOG_ERROR, "samba_dlz b9_record_match: unhandled record type %u", rec1->wType); break; } diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index da452e6..ecb5315 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -38,14 +38,19 @@ struct dcerpc_pipe_connect { struct dcecli_connection *conn; - const struct dcerpc_binding *binding; - const char *pipe_name; + struct dcerpc_binding *binding; const struct ndr_interface_table *interface; struct cli_credentials *creds; struct resolve_context *resolve_ctx; struct { const char *dir; } ncalrpc; + struct { + struct smbXcli_conn *conn; + struct smbXcli_session *session; + struct smbXcli_tcon *tcon; + const char *pipe_name; + } smb; }; struct pipe_np_smb_state { @@ -69,46 +74,49 @@ static void continue_pipe_open_smb(struct composite_context *ctx) composite_done(c); } +static void continue_smb_open(struct composite_context *c); /* Stage 2 of ncacn_np_smb: Open a named pipe after successful smb connection */ static void continue_smb_connect(struct composite_context *ctx) { - struct composite_context *open_ctx; struct composite_context *c = talloc_get_type(ctx->async.private_data, struct composite_context); struct pipe_np_smb_state *s = talloc_get_type(c->private_data, struct pipe_np_smb_state); struct smbcli_tree *t; - struct smbXcli_conn *conn; - struct smbXcli_session *session; - struct smbXcli_tcon *tcon; - uint32_t timeout_msec; /* receive result of smb connect request */ c->status = smb_composite_connect_recv(ctx, s->io.conn); if (!composite_is_ok(c)) return; + t = s->conn.out.tree; + /* prepare named pipe open parameters */ - s->io.pipe_name = dcerpc_binding_get_string_option(s->io.binding, "endpoint"); - if (s->io.pipe_name == NULL) { - composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX); - return; - } + s->io.smb.conn = t->session->transport->conn; + s->io.smb.session = t->session->smbXcli; + s->io.smb.tcon = t->smbXcli; + smb1cli_tcon_set_id(s->io.smb.tcon, t->tid); + s->io.smb.pipe_name = dcerpc_binding_get_string_option(s->io.binding, + "endpoint"); + + continue_smb_open(c); +} - t = s->conn.out.tree; - conn = t->session->transport->conn; - session = t->session->smbXcli; - tcon = t->smbXcli; - smb1cli_tcon_set_id(tcon, t->tid); - timeout_msec = t->session->transport->options.request_timeout * 1000; +static void continue_smb_open(struct composite_context *c) +{ + struct pipe_np_smb_state *s = talloc_get_type(c->private_data, + struct pipe_np_smb_state); + struct composite_context *open_ctx; /* send named pipe open request */ open_ctx = dcerpc_pipe_open_smb_send(s->io.conn, - conn, session, - tcon, timeout_msec, - s->io.pipe_name); + s->io.smb.conn, + s->io.smb.session, + s->io.smb.tcon, + DCERPC_REQUEST_TIMEOUT * 1000, + s->io.smb.pipe_name); if (composite_nomem(open_ctx, c)) return; composite_continue(c, open_ctx, continue_pipe_open_smb, c); @@ -138,6 +146,11 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT s->io = *io; conn = &s->conn; + if (smbXcli_conn_is_connected(s->io.smb.conn)) { + continue_smb_open(c); + return c; + } + /* prepare smb connection parameters: we're connecting to IPC$ share on remote rpc server */ conn->in.dest_host = dcerpc_binding_get_string_option(s->io.binding, "host"); @@ -192,70 +205,30 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np_smb_recv(struct composite_context * return status; } - -struct pipe_np_smb2_state { - struct dcerpc_pipe_connect io; -}; - - -/* - Stage 3 of ncacn_np_smb: Named pipe opened (or not) -*/ -static void continue_pipe_open_smb2(struct composite_context *ctx) -{ - struct composite_context *c = talloc_get_type(ctx->async.private_data, - struct composite_context); - - /* receive result of named pipe open request on smb2 */ - c->status = dcerpc_pipe_open_smb_recv(ctx); - if (!composite_is_ok(c)) return; - - composite_done(c); -} - - /* Stage 2 of ncacn_np_smb2: Open a named pipe after successful smb2 connection */ static void continue_smb2_connect(struct tevent_req *subreq) { - struct composite_context *open_req; struct composite_context *c = tevent_req_callback_data(subreq, struct composite_context); - struct pipe_np_smb2_state *s = talloc_get_type(c->private_data, - struct pipe_np_smb2_state); + struct pipe_np_smb_state *s = talloc_get_type(c->private_data, + struct pipe_np_smb_state); struct smb2_tree *t; - struct smbXcli_conn *conn; - struct smbXcli_session *session; - struct smbXcli_tcon *tcon; - uint32_t timeout_msec; /* receive result of smb2 connect request */ c->status = smb2_connect_recv(subreq, s->io.conn, &t); TALLOC_FREE(subreq); if (!composite_is_ok(c)) return; - /* prepare named pipe open parameters */ - s->io.pipe_name = dcerpc_binding_get_string_option(s->io.binding, "endpoint"); - if (s->io.pipe_name == NULL) { - composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX); - return; - } - - conn = t->session->transport->conn; - session = t->session->smbXcli; - tcon = t->smbXcli; - timeout_msec = t->session->transport->options.request_timeout * 1000; - - /* send named pipe open request */ - open_req = dcerpc_pipe_open_smb_send(s->io.conn, - conn, session, - tcon, timeout_msec, - s->io.pipe_name); - if (composite_nomem(open_req, c)) return; + s->io.smb.conn = t->session->transport->conn; + s->io.smb.session = t->session->smbXcli; + s->io.smb.tcon = t->smbXcli; + s->io.smb.pipe_name = dcerpc_binding_get_string_option(s->io.binding, + "endpoint"); - composite_continue(c, open_req, continue_pipe_open_smb2, c); + continue_smb_open(c); } @@ -269,7 +242,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send( struct loadparm_context *lp_ctx) { struct composite_context *c; - struct pipe_np_smb2_state *s; + struct pipe_np_smb_state *s; struct tevent_req *subreq; struct smbcli_options options; const char *host; @@ -279,12 +252,17 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send( c = composite_create(mem_ctx, io->conn->event_ctx); if (c == NULL) return NULL; - s = talloc_zero(c, struct pipe_np_smb2_state); + s = talloc_zero(c, struct pipe_np_smb_state); if (composite_nomem(s, c)) return c; c->private_data = s; s->io = *io; + if (smbXcli_conn_is_connected(s->io.smb.conn)) { + continue_smb_open(c); + return c; + } + host = dcerpc_binding_get_string_option(s->io.binding, "host"); flags = dcerpc_binding_get_flags(s->io.binding); @@ -344,9 +322,23 @@ static void continue_pipe_open_ncacn_ip_tcp(struct composite_context *ctx) { struct composite_context *c = talloc_get_type(ctx->async.private_data, struct composite_context); + struct pipe_ip_tcp_state *s = talloc_get_type(c->private_data, + struct pipe_ip_tcp_state); + char *localaddr = NULL; + char *remoteaddr = NULL; /* receive result of named pipe open request on tcp/ip */ - c->status = dcerpc_pipe_open_tcp_recv(ctx); + c->status = dcerpc_pipe_open_tcp_recv(ctx, s, &localaddr, &remoteaddr); + if (!composite_is_ok(c)) return; + + c->status = dcerpc_binding_set_string_option(s->io.binding, + "localaddress", + localaddr); + if (!composite_is_ok(c)) return; + + c->status = dcerpc_binding_set_string_option(s->io.binding, + "host", + remoteaddr); if (!composite_is_ok(c)) return; composite_done(c); @@ -614,7 +606,6 @@ static void continue_connect(struct composite_context *c, struct pipe_connect_st ZERO_STRUCT(pc); pc.conn = s->pipe->conn; pc.binding = s->binding; - pc.pipe_name = NULL; pc.interface = s->table; pc.creds = s->credentials; pc.resolve_ctx = lpcfg_resolve_context(s->lp_ctx); diff --git a/source4/librpc/rpc/dcerpc_secondary.c b/source4/librpc/rpc/dcerpc_secondary.c index be886a2..9f52345 100644 --- a/source4/librpc/rpc/dcerpc_secondary.c +++ b/source4/librpc/rpc/dcerpc_secondary.c @@ -31,20 +31,19 @@ #include "auth/credentials/credentials.h" #include "param/param.h" #include "libcli/resolve/resolve.h" -#include "lib/socket/socket.h" +#include "lib/util/util_net.h" struct sec_conn_state { struct dcerpc_pipe *pipe; struct dcerpc_pipe *pipe2; - const struct dcerpc_binding *binding; - struct socket_address *peer_addr; - const char *localaddress; + struct dcerpc_binding *binding; }; static void continue_open_smb(struct composite_context *ctx); static void continue_open_tcp(struct composite_context *ctx); -static void continue_open_pipe(struct composite_context *ctx); +static void continue_open_ncalrpc(struct composite_context *ctx); +static void continue_open_ncacn_unix(struct composite_context *ctx); static void continue_pipe_open(struct composite_context *c); @@ -59,7 +58,11 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp struct sec_conn_state *s; struct composite_context *pipe_smb_req; struct composite_context *pipe_tcp_req; + const char *localaddress = NULL; struct composite_context *pipe_ncalrpc_req; + const char *ncalrpc_dir = NULL; + struct composite_context *pipe_unix_req; + const char *host; const char *target_hostname; const char *endpoint; @@ -72,7 +75,8 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp c->private_data = s; s->pipe = p; - s->binding = b; + s->binding = dcerpc_binding_dup(s, b); + if (composite_nomem(s->binding, c)) return c; /* initialise second dcerpc pipe based on primary pipe's event context */ s->pipe2 = dcerpc_pipe_init(c, s->pipe->conn->event_ctx); @@ -81,7 +85,22 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp if (DEBUGLEVEL >= 10) s->pipe2->conn->packet_log_dir = s->pipe->conn->packet_log_dir; + host = dcerpc_binding_get_string_option(s->binding, "host"); + if (host == NULL) { + /* + * We may fallback to the host of the given connection + */ + host = dcerpc_binding_get_string_option(s->pipe->binding, + "host"); + } target_hostname = dcerpc_binding_get_string_option(s->binding, "target_hostname"); + if (target_hostname == NULL) { + /* + * We may fallback to the target_hostname of the given connection + */ + target_hostname = dcerpc_binding_get_string_option(s->pipe->binding, + "target_hostname"); + } endpoint = dcerpc_binding_get_string_option(s->binding, "endpoint"); if (endpoint == NULL) { /* @@ -104,18 +123,40 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp return c; case NCACN_IP_TCP: - s->peer_addr = dcerpc_socket_peer_addr(s->pipe->conn, s); - if (!s->peer_addr) { - composite_error(c, NT_STATUS_INVALID_PARAMETER); + if (host == NULL) { + composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX); return c; } - s->localaddress = dcerpc_binding_get_string_option(s->binding, + if (!is_ipaddress(host)) { + /* + * We may fallback to the host of the given connection + */ + host = dcerpc_binding_get_string_option(s->pipe->binding, + "host"); + if (host == NULL) { + composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX); + return c; + } + if (!is_ipaddress(host)) { + composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX); + return c; + } + } + + localaddress = dcerpc_binding_get_string_option(s->binding, "localaddress"); + if (localaddress == NULL) { + /* + * We may fallback to the localaddress of the given connection + */ + localaddress = dcerpc_binding_get_string_option(s->pipe->binding, + "localaddress"); + } pipe_tcp_req = dcerpc_pipe_open_tcp_send(s->pipe2->conn, - s->localaddress, - s->peer_addr->addr, + localaddress, + host, target_hostname, atoi(endpoint), resolve_context_init(s)); @@ -123,10 +164,27 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp return c; case NCALRPC: + ncalrpc_dir = dcerpc_binding_get_string_option(s->binding, + "ncalrpc_dir"); + if (ncalrpc_dir == NULL) { + ncalrpc_dir = dcerpc_binding_get_string_option(s->pipe->binding, + "ncalrpc_dir"); + } + if (ncalrpc_dir == NULL) { + composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX); + return c; + } + + pipe_ncalrpc_req = dcerpc_pipe_open_pipe_send(s->pipe2->conn, + ncalrpc_dir, + endpoint); + composite_continue(c, pipe_ncalrpc_req, continue_open_ncalrpc, c); + return c; + case NCACN_UNIX_STREAM: - pipe_ncalrpc_req = dcerpc_pipe_open_unix_stream_send(s->pipe2->conn, - dcerpc_unix_socket_path(s->pipe->conn)); - composite_continue(c, pipe_ncalrpc_req, continue_open_pipe, c); + pipe_unix_req = dcerpc_pipe_open_unix_stream_send(s->pipe2->conn, + endpoint); + composite_continue(c, pipe_unix_req, continue_open_ncacn_unix, c); return c; default: @@ -160,18 +218,45 @@ static void continue_open_tcp(struct composite_context *ctx) { struct composite_context *c = talloc_get_type(ctx->async.private_data, struct composite_context); - - c->status = dcerpc_pipe_open_tcp_recv(ctx); + struct sec_conn_state *s = talloc_get_type_abort(c->private_data, + struct sec_conn_state); + char *localaddr = NULL; + char *remoteaddr = NULL; + + c->status = dcerpc_pipe_open_tcp_recv(ctx, s, &localaddr, &remoteaddr); + if (!composite_is_ok(c)) return; + + c->status = dcerpc_binding_set_string_option(s->binding, + "localaddress", + localaddr); + if (!composite_is_ok(c)) return; + + c->status = dcerpc_binding_set_string_option(s->binding, + "host", + remoteaddr); if (!composite_is_ok(c)) return; continue_pipe_open(c); } - /* Stage 2 of secondary_connection: Receive result of pipe open request on ncalrpc */ -static void continue_open_pipe(struct composite_context *ctx) +static void continue_open_ncalrpc(struct composite_context *ctx) +{ + struct composite_context *c = talloc_get_type(ctx->async.private_data, + struct composite_context); + + c->status = dcerpc_pipe_open_pipe_recv(ctx); + if (!composite_is_ok(c)) return; + + continue_pipe_open(c); +} -- Samba Shared Repository