[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Sun May 25 21:56:04 MDT 2014


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 <requate at 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 <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Kai Blin <kai at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Mon May 26 05:55:46 CEST 2014 on sn-devel-104

commit f15d10df29285024eae75eb83e03ff14d22524e6
Author: Arvid Requate <requate at 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 <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Kai Blin <kai at samba.org>
    Reviewed-by: Guenter Kukkukk <kukks at samba.org>

commit 13b36be68fb54d8e993aefe7b8b5e53f7316a126
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a13eebac7dbc4c496e3784d2b31be89670dddb6d
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 35192e8316291daf70576ceeb483c0204ec9d455
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7ea04759d7f94a5d4fa57a63612afd9e752ba5e9
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ae406ac6687a5c093e196741ac0187cf27a83b3d
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d1b5016572a3d1fe45a50015bcaf7ecb51ed6a4d
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e4f7b90295c461da8acdf1c4f23ae02c00211ed1
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3aebaf4c1340292baec0db8448e60af2079600c1
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 374c5c4109facbcf3e9a20d1b116d369f14164c0
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4c11fa68d48caa06d6f9c9db462a2d2e6a0bc3d3
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit dfee05744797459d1303a54edb5955dec1e4cb1a
Author: Stefan Metzmacher <metze at 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 <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at 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


More information about the samba-cvs mailing list