[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Mon Sep 6 17:59:48 MDT 2010


The branch, master has been updated
       via  e5e5a11 Add unique IP address binding for client connections (EPM and ncacn_ip_tcp levels)
      from  35aed17 s4-test: refactor API-DELETEUSER test a little to:

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e5e5a1110fb4092a1221512627b1f9d03ec8839c
Author: Julien Kerihuel <j.kerihuel at openchange.org>
Date:   Fri Aug 27 14:04:07 2010 +0200

    Add unique IP address binding for client connections (EPM and ncacn_ip_tcp levels)
    
    This allows for binding strings like this:
    
      ncacn_ip_tcp:host[localaddress=192.168.2.1,seal]
    
    which will force the connection to be locally bound to the specified
    IP address
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 librpc/rpc/binding.c                  |   22 +++++++++++++++++++---
 source3/librpc/rpc/dcerpc.h           |    4 ++++
 source4/librpc/rpc/dcerpc.h           |    4 ++++
 source4/librpc/rpc/dcerpc_connect.c   |    4 +++-
 source4/librpc/rpc/dcerpc_secondary.c |    1 +
 source4/librpc/rpc/dcerpc_sock.c      |   25 +++++++++++++++++++------
 source4/librpc/rpc/dcerpc_util.c      |    1 +
 source4/librpc/tests/binding_string.c |    6 ++++++
 8 files changed, 57 insertions(+), 10 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c
index 5e9bef8..feff512 100644
--- a/librpc/rpc/binding.c
+++ b/librpc/rpc/binding.c
@@ -86,7 +86,8 @@ static const struct {
 	{"bigendian", DCERPC_PUSH_BIGENDIAN},
 	{"smb2", DCERPC_SMB2},
 	{"hdrsign", DCERPC_HEADER_SIGNING},
-	{"ndr64", DCERPC_NDR64}
+	{"ndr64", DCERPC_NDR64},
+	{"localaddress", DCERPC_LOCALADDRESS}
 };
 
 const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
@@ -220,7 +221,12 @@ _PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bi
 
 	for (i=0;i<ARRAY_SIZE(ncacn_options);i++) {
 		if (b->flags & ncacn_options[i].flag) {
-			s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name);
+			if (ncacn_options[i].flag == DCERPC_LOCALADDRESS && b->localaddress) {
+				s = talloc_asprintf_append_buffer(s, ",%s=%s", ncacn_options[i].name,
+								  b->localaddress);
+			} else {
+				s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name);
+			}
 			if (!s) return NULL;
 		}
 	}
@@ -313,6 +319,7 @@ _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struc
 	b->flags = 0;
 	b->assoc_group_id = 0;
 	b->endpoint = NULL;
+	b->localaddress = NULL;
 
 	if (!options) {
 		*b_out = b;
@@ -339,8 +346,17 @@ _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struc
 	/* some options are pre-parsed for convenience */
 	for (i=0;b->options[i];i++) {
 		for (j=0;j<ARRAY_SIZE(ncacn_options);j++) {
-			if (strcasecmp(ncacn_options[j].name, b->options[i]) == 0) {
+			size_t opt_len = strlen(ncacn_options[j].name);
+			if (strncasecmp(ncacn_options[j].name, b->options[i], opt_len) == 0) {
 				int k;
+				char c = b->options[i][opt_len];
+
+				if (ncacn_options[j].flag == DCERPC_LOCALADDRESS && c == '=') {
+					b->localaddress = talloc_strdup(b, &b->options[i][opt_len+1]);
+				} else if (c != 0) {
+					continue;
+				}
+
 				b->flags |= ncacn_options[j].flag;
 				for (k=i;b->options[k];k++) {
 					b->options[k] = b->options[k+1];
diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
index af20889..56d6d32 100644
--- a/source3/librpc/rpc/dcerpc.h
+++ b/source3/librpc/rpc/dcerpc.h
@@ -41,6 +41,7 @@ struct dcerpc_binding {
 	const char *target_hostname;
 	const char *endpoint;
 	const char **options;
+	const char *localaddress;
 	uint32_t flags;
 	uint32_t assoc_group_id;
 };
@@ -95,6 +96,9 @@ struct dcerpc_binding {
 /* use NDR64 transport */
 #define DCERPC_NDR64                   (1<<21)
 
+/* specify binding interface */
+#define	DCERPC_LOCALADDRESS            (1<<22)
+
 /* The following definitions come from librpc/rpc/binding.c  */
 
 const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor);
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index b77628d..b5062a5 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -181,6 +181,9 @@ struct dcerpc_pipe {
 /* use NDR64 transport */
 #define DCERPC_NDR64                   (1<<21)
 
+/* specify binding interface */
+#define	DCERPC_LOCALADDRESS            (1<<22)
+
 /* this describes a binding to a particular transport/pipe */
 struct dcerpc_binding {
 	enum dcerpc_transport_t transport;
@@ -189,6 +192,7 @@ struct dcerpc_binding {
 	const char *target_hostname;
 	const char *endpoint;
 	const char **options;
+	const char *localaddress;
 	uint32_t flags;
 	uint32_t assoc_group_id;
 };
diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c
index 7779d31..0f3a862 100644
--- a/source4/librpc/rpc/dcerpc_connect.c
+++ b/source4/librpc/rpc/dcerpc_connect.c
@@ -276,6 +276,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np_smb2_recv(struct composite_context
 
 struct pipe_ip_tcp_state {
 	struct dcerpc_pipe_connect io;
+	const char *localaddr;
 	const char *host;
 	const char *target_hostname;
 	uint32_t port;
@@ -319,13 +320,14 @@ static struct composite_context* dcerpc_pipe_connect_ncacn_ip_tcp_send(TALLOC_CT
 
 	/* store input parameters in state structure */
 	s->io               = *io;
+	s->localaddr        = talloc_reference(c, io->binding->localaddress);
 	s->host             = talloc_reference(c, io->binding->host);
 	s->target_hostname  = talloc_reference(c, io->binding->target_hostname);
                              /* port number is a binding endpoint here */
 	s->port             = atoi(io->binding->endpoint);   
 
 	/* send pipe open request on tcp/ip */
-	pipe_req = dcerpc_pipe_open_tcp_send(s->io.pipe->conn, s->host, s->target_hostname, 
+	pipe_req = dcerpc_pipe_open_tcp_send(s->io.pipe->conn, s->localaddr, s->host, s->target_hostname,
 					     s->port, io->resolve_ctx);
 	composite_continue(c, pipe_req, continue_pipe_open_ncacn_ip_tcp, c);
 	return c;
diff --git a/source4/librpc/rpc/dcerpc_secondary.c b/source4/librpc/rpc/dcerpc_secondary.c
index 5f355a5..65466e4 100644
--- a/source4/librpc/rpc/dcerpc_secondary.c
+++ b/source4/librpc/rpc/dcerpc_secondary.c
@@ -102,6 +102,7 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp
 		}
 
 		pipe_tcp_req = dcerpc_pipe_open_tcp_send(s->pipe2->conn,
+							 s->binding->localaddress,
 							 s->peer_addr->addr,
 							 s->binding->target_hostname,
 							 atoi(s->binding->endpoint),
diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c
index d8bd6d2..4ab8c35 100644
--- a/source4/librpc/rpc/dcerpc_sock.c
+++ b/source4/librpc/rpc/dcerpc_sock.c
@@ -228,6 +228,7 @@ struct pipe_open_socket_state {
 	struct dcerpc_connection *conn;
 	struct socket_context *socket_ctx;
 	struct sock_private *sock;
+	struct socket_address *localaddr;
 	struct socket_address *server;
 	const char *target_hostname;
 	enum dcerpc_transport_t transport;
@@ -305,6 +306,7 @@ static void continue_socket_connect(struct composite_context *ctx)
 
 static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ctx,
 						       struct dcerpc_connection *cn,
+						       struct socket_address *localaddr,
 						       struct socket_address *server,
 						       const char *target_hostname,
 						       const char *full_path,
@@ -323,6 +325,10 @@ static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ct
 
 	s->conn      = cn;
 	s->transport = transport;
+	if (localaddr) {
+		s->localaddr = talloc_reference(c, localaddr);
+		if (composite_nomem(s->localaddr, c)) return c;
+	}
 	s->server    = talloc_reference(c, server);
 	if (composite_nomem(s->server, c)) return c;
 	s->target_hostname = talloc_reference(s, target_hostname);
@@ -337,7 +343,7 @@ static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ct
 
 	s->sock->path = talloc_reference(s->sock, full_path);
 
-	conn_req = socket_connect_send(s->socket_ctx, NULL, s->server, 0, 
+	conn_req = socket_connect_send(s->socket_ctx, s->localaddr, s->server, 0,
 				       c->event_ctx);
 	composite_continue(c, conn_req, continue_socket_connect, c);
 	return c;
@@ -357,6 +363,7 @@ struct pipe_tcp_state {
 	const char *target_hostname;
 	const char *address;
 	uint32_t port;
+	struct socket_address *localaddr;
 	struct socket_address *srvaddr;
 	struct resolve_context *resolve_ctx;
 	struct dcerpc_connection *conn;
@@ -385,7 +392,7 @@ static void continue_ip_resolve_name(struct composite_context *ctx)
 	if (composite_nomem(s->srvaddr, c)) return;
 
 	/* resolve_nbt_name gives only ipv4 ... - send socket open request */
-	sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn,
+	sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr,
 						     s->srvaddr, s->target_hostname,
 						     NULL,
 						     NCACN_IP_TCP);
@@ -419,7 +426,7 @@ static void continue_ipv6_open_socket(struct composite_context *ctx)
 	if (composite_nomem(s->srvaddr, c)) return;
 
 	/* try IPv4 if IPv6 fails */
-	sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, 
+	sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr,
 						     s->srvaddr, s->target_hostname, 
 						     NCACN_IP_TCP);
 	composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c);
@@ -452,12 +459,12 @@ static void continue_ipv4_open_socket(struct composite_context *ctx)
 	composite_done(c);
 }
 
-
 /*
   Send rpc pipe open request to given host:port using
   tcp/ip transport
 */
 struct composite_context* dcerpc_pipe_open_tcp_send(struct dcerpc_connection *conn,
+						    const char *localaddr,
 						    const char *server,
 						    const char *target_hostname,
 						    uint32_t port,
@@ -486,6 +493,12 @@ struct composite_context* dcerpc_pipe_open_tcp_send(struct dcerpc_connection *co
 	s->port            = port;
 	s->conn            = conn;
 	s->resolve_ctx     = resolve_ctx;
+	if (localaddr) {
+		s->localaddr = socket_address_from_strings(s, "ip", localaddr, 0);
+		/* if there is no localaddr, we pass NULL for
+		   s->localaddr, which is handled by the socket libraries as
+		   meaning no local binding address specified */
+	}
 
 	make_nbt_name_server(&name, server);
 	resolve_req = resolve_name_send(resolve_ctx, s, &name, c->event_ctx);
@@ -560,7 +573,7 @@ struct composite_context *dcerpc_pipe_open_unix_stream_send(struct dcerpc_connec
 	if (composite_nomem(s->srvaddr, c)) return c;
 
 	/* send socket open request */
-	sock_unix_req = dcerpc_pipe_open_socket_send(c, s->conn, 
+	sock_unix_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL,
 						     s->srvaddr, NULL,
 						     s->path,
 						     NCALRPC);
@@ -631,7 +644,7 @@ struct composite_context* dcerpc_pipe_open_pipe_send(struct dcerpc_connection *c
 	if (composite_nomem(s->srvaddr, c)) return c;
 
 	/* send socket open request */
-	sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, s->srvaddr, NULL, s->path, NCALRPC);
+	sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL, s->srvaddr, NULL, s->path, NCALRPC);
 	composite_continue(c, sock_np_req, continue_np_open_socket, c);
 	return c;
 }
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index ffe8506..d27b0f3 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -285,6 +285,7 @@ struct composite_context *dcerpc_epm_map_binding_send(TALLOC_CTX *mem_ctx,
 	epmapper_binding->host			= talloc_reference(epmapper_binding, binding->host);
 	epmapper_binding->target_hostname       = epmapper_binding->host;
 	epmapper_binding->options		= NULL;
+	epmapper_binding->localaddress          = talloc_reference(epmapper_binding, binding->localaddress);
 	epmapper_binding->flags			= 0;
 	epmapper_binding->assoc_group_id	= 0;
 	epmapper_binding->endpoint		= NULL;
diff --git a/source4/librpc/tests/binding_string.c b/source4/librpc/tests/binding_string.c
index 6de94eb..dfb6d29 100644
--- a/source4/librpc/tests/binding_string.c
+++ b/source4/librpc/tests/binding_string.c
@@ -128,6 +128,12 @@ static bool test_parse_check_results(struct torture_context *tctx)
 	torture_assert_int_equal(tctx, b->object.if_version, 0, "object version");
 	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, 
 		"308FB580-1EB2-11CA-923B-08002B1075A7 at ncacn_ip_tcp:$SERVER", &b), "parse");
+	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]", &b), "parse");
+	torture_assert(tctx, b->transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
+	torture_assert(tctx, b->flags == (DCERPC_SIGN | DCERPC_LOCALADDRESS), "sign flag");
+	torture_assert_str_equal(tctx, b->localaddress, "192.168.1.1", "localaddress");
+	torture_assert_str_equal(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]",
+				 dcerpc_binding_string(tctx, b), "back to string");
 
 	return true;
 }


-- 
Samba Shared Repository


More information about the samba-cvs mailing list