svn commit: samba r19266 - in branches/SAMBA_4_0/source: libnet librpc/rpc torture/rpc

abartlet at samba.org abartlet at samba.org
Fri Oct 13 13:01:49 GMT 2006


Author: abartlet
Date: 2006-10-13 13:01:48 +0000 (Fri, 13 Oct 2006)
New Revision: 19266

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=19266

Log:
Add a target_hostname element to the binding struct.  This allows us
to perform a lookup once, resolve the name to an IP, while still
communicating the full name to the lower layers, for kerberos etc.

This fixes 'net samdump', which was failing due to the schannel target
name being *smbserver.

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/libnet/libnet_join.c
   branches/SAMBA_4_0/source/libnet/libnet_rpc.c
   branches/SAMBA_4_0/source/libnet/libnet_rpc.h
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc.h
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc_connect.c
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc_sock.c
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c
   branches/SAMBA_4_0/source/torture/rpc/async_bind.c


Changeset:
Modified: branches/SAMBA_4_0/source/libnet/libnet_join.c
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_join.c	2006-10-13 12:54:13 UTC (rev 19265)
+++ branches/SAMBA_4_0/source/libnet/libnet_join.c	2006-10-13 13:01:48 UTC (rev 19266)
@@ -229,7 +229,7 @@
 	/* Now we know the user's DN, open with LDAP, read and modify a few things */
 
 	remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s", 
-					 drsuapi_binding->host);
+					 drsuapi_binding->target_hostname);
 	if (!remote_ldb_url) {
 		r->out.error_string = NULL;
 		talloc_free(tmp_ctx);

Modified: branches/SAMBA_4_0/source/libnet/libnet_rpc.c
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_rpc.c	2006-10-13 12:54:13 UTC (rev 19265)
+++ branches/SAMBA_4_0/source/libnet/libnet_rpc.c	2006-10-13 13:01:48 UTC (rev 19266)
@@ -53,6 +53,7 @@
 {
 	struct composite_context *c;	
 	struct rpc_connect_srv_state *s;
+	struct dcerpc_binding *b;
 	struct composite_context *pipe_connect_req;
 
 	/* composite context allocation and setup */
@@ -72,16 +73,21 @@
 
 	/* prepare binding string */
 	switch (r->level) {
-	case LIBNET_RPC_CONNECT_DC:
-	case LIBNET_RPC_CONNECT_PDC:
 	case LIBNET_RPC_CONNECT_SERVER:
 		s->binding = talloc_asprintf(s, "ncacn_np:%s", r->in.name);
 		break;
+	case LIBNET_RPC_CONNECT_SERVER_ADDRESS:
+		s->binding = talloc_asprintf(s, "ncacn_np:%s", r->in.address);
+		break;
 
 	case LIBNET_RPC_CONNECT_BINDING:
 		s->binding = talloc_strdup(s, r->in.binding);
 		break;
 
+	case LIBNET_RPC_CONNECT_DC:
+	case LIBNET_RPC_CONNECT_PDC:
+		/* this should never happen - DC and PDC level has a separate
+		   composite function */
 	case LIBNET_RPC_CONNECT_DC_INFO:
 		/* this should never happen - DC_INFO level has a separate
 		   composite function */
@@ -89,9 +95,23 @@
 		return c;
 	}
 
+	/* parse binding string to the structure */
+	c->status = dcerpc_parse_binding(c, s->binding, &b);
+	if (!NT_STATUS_IS_OK(c->status)) {
+		DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", s->binding));
+		composite_error(c, c->status);
+		return c;
+	}
+
+	if (r->level == LIBNET_RPC_CONNECT_SERVER_ADDRESS) {
+		b->target_hostname = talloc_reference(b, r->in.name);
+		if (composite_nomem(b->target_hostname, c)) {
+			return c;
+		}
+	}
+
 	/* connect to remote dcerpc pipe */
-	pipe_connect_req = dcerpc_pipe_connect_send(c, &s->r.out.dcerpc_pipe,
-						    s->binding, r->in.dcerpc_iface,
+	pipe_connect_req = dcerpc_pipe_connect_b_send(c, b, r->in.dcerpc_iface,
 						    ctx->cred, c->event_ctx);
 	if (composite_nomem(pipe_connect_req, c)) return c;
 
@@ -112,7 +132,7 @@
 	s = talloc_get_type(c->private_data, struct rpc_connect_srv_state);
 
 	/* receive result of rpc pipe connection */
-	c->status = dcerpc_pipe_connect_recv(ctx, c, &s->r.out.dcerpc_pipe);
+	c->status = dcerpc_pipe_connect_b_recv(ctx, c, &s->r.out.dcerpc_pipe);
 
 	s->r.out.error_string = NULL;
 	composite_done(c);
@@ -237,7 +257,7 @@
 
 
 /*
-  Step 2 of RpcConnectDC: get domain controller name/address and
+  Step 2 of RpcConnectDC: get domain controller name and
   initiate RpcConnect to it
 */
 static void continue_lookup_dc(struct composite_context *ctx)
@@ -256,20 +276,8 @@
 	if (!composite_is_ok(c)) return;
 
 	/* decide on preferred address type depending on DC type */
-	switch (s->r.level) {
-	case LIBNET_RPC_CONNECT_PDC:
-		s->connect_name = s->f.out.dcs[0].name;
-		break;
+	s->connect_name = s->f.out.dcs[0].name;
 
-	case LIBNET_RPC_CONNECT_DC:
-		s->connect_name = s->f.out.dcs[0].address;
-		break;
-
-	default:
-		/* we shouldn't absolutely get here */
-		composite_error(c, NT_STATUS_INVALID_LEVEL);
-	}
-
 	/* prepare a monitor message and post it */
 	msg.type         = net_lookup_dc;
 	msg.data         = &data;
@@ -282,11 +290,12 @@
 	if (s->monitor_fn) s->monitor_fn(&msg);
 
 	/* ok, pdc has been found so do attempt to rpc connect */
-	s->r2.level	       = s->r.level;
+	s->r2.level	       = LIBNET_RPC_CONNECT_SERVER_ADDRESS;
 
 	/* this will cause yet another name resolution, but at least
 	 * we pass the right name down the stack now */
-	s->r2.in.name          = talloc_strdup(c, s->connect_name);
+	s->r2.in.name          = talloc_strdup(s, s->connect_name);
+	s->r2.in.address       = talloc_steal(s, s->f.out.dcs[0].address);
 	s->r2.in.dcerpc_iface  = s->r.in.dcerpc_iface;	
 
 	/* send rpc connect request to the server */
@@ -630,7 +639,7 @@
 	
 	*s->final_binding = *s->lsa_pipe->binding;
 	/* Ensure we keep hold of the member elements */
-	talloc_reference(s->final_binding, s->lsa_pipe->binding);
+	if (composite_nomem(talloc_reference(s->final_binding, s->lsa_pipe->binding), c)) return;
 
 	epm_map_req = dcerpc_epm_map_binding_send(c, s->final_binding, s->r.in.dcerpc_iface,
 						  s->lsa_pipe->conn->event_ctx);
@@ -735,7 +744,11 @@
 		}
 
 	} else {
-		r->out.error_string = talloc_steal(mem_ctx, s->r.out.error_string);
+		if (s->r.out.error_string) {
+			r->out.error_string = talloc_steal(mem_ctx, s->r.out.error_string);
+		} else {
+			r->out.error_string = talloc_asprintf(mem_ctx, "Connection to DC failed: %s", nt_errstr(status));
+		}
 	}
 
 	talloc_free(c);
@@ -761,6 +774,7 @@
 
 	switch (r->level) {
 	case LIBNET_RPC_CONNECT_SERVER:
+	case LIBNET_RPC_CONNECT_SERVER_ADDRESS:
 	case LIBNET_RPC_CONNECT_BINDING:
 		c = libnet_RpcConnectSrv_send(ctx, mem_ctx, r);
 		break;

Modified: branches/SAMBA_4_0/source/libnet/libnet_rpc.h
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_rpc.h	2006-10-13 12:54:13 UTC (rev 19265)
+++ branches/SAMBA_4_0/source/libnet/libnet_rpc.h	2006-10-13 13:01:48 UTC (rev 19266)
@@ -26,14 +26,16 @@
  */
 
 enum libnet_RpcConnect_level {
-	LIBNET_RPC_CONNECT_SERVER,       /* connect to a standalone rpc server */
-	LIBNET_RPC_CONNECT_PDC,          /* connect to a domain pdc (resolves domain
-					    name to a pdc address before connecting) */
-	LIBNET_RPC_CONNECT_DC,           /* connect to any DC (resolves domain
-					    name to a DC address before connecting) */
-	LIBNET_RPC_CONNECT_BINDING,      /* specified binding string */
-	LIBNET_RPC_CONNECT_DC_INFO       /* connect to a DC and provide basic domain
-					    information (name, realm, sid, guid) */
+	LIBNET_RPC_CONNECT_SERVER,          /* connect to a standalone rpc server */
+	LIBNET_RPC_CONNECT_SERVER_ADDRESS,  /* connect to a standalone rpc server, 
+					       knowing both name and address */
+	LIBNET_RPC_CONNECT_PDC,             /* connect to a domain pdc (resolves domain
+					       name to a pdc address before connecting) */
+	LIBNET_RPC_CONNECT_DC,              /* connect to any DC (resolves domain
+					       name to a DC address before connecting) */
+	LIBNET_RPC_CONNECT_BINDING,         /* specified binding string */
+	LIBNET_RPC_CONNECT_DC_INFO          /* connect to a DC and provide basic domain
+					       information (name, realm, sid, guid) */
 };
 
 struct libnet_RpcConnect {
@@ -41,6 +43,7 @@
 
 	struct {
 		const char *name;
+		const char *address;
 		const char *binding;
 		const struct dcerpc_interface_table *dcerpc_iface;
 	} in;

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc.h
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc.h	2006-10-13 12:54:13 UTC (rev 19265)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc.h	2006-10-13 13:01:48 UTC (rev 19266)
@@ -193,6 +193,7 @@
 	enum dcerpc_transport_t transport;
 	struct dcerpc_syntax_id object;
 	const char *host;
+	const char *target_hostname;
 	const char *endpoint;
 	const char **options;
 	uint32_t flags;

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc_connect.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc_connect.c	2006-10-13 12:54:13 UTC (rev 19265)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc_connect.c	2006-10-13 13:01:48 UTC (rev 19266)
@@ -111,14 +111,11 @@
 	   remote rpc server */
 	conn->in.dest_host              = s->io.binding->host;
 	conn->in.port                   = 0;
-	conn->in.called_name            = strupper_talloc(mem_ctx, s->io.binding->host);
+	conn->in.called_name            = s->io.binding->target_hostname;
 	conn->in.service                = "IPC$";
 	conn->in.service_type           = NULL;
 	conn->in.workgroup              = lp_workgroup();
 
-	/* verify if called_name has been allocated when uppercasing */
-	if (composite_nomem(conn->in.called_name, c)) return c;
-
 	/*
 	 * provide proper credentials - user supplied, but allow a
 	 * fallback to anonymous if this is an schannel connection
@@ -281,6 +278,7 @@
 struct pipe_ip_tcp_state {
 	struct dcerpc_pipe_connect io;
 	const char *host;
+	const char *target_hostname;
 	uint32_t port;
 };
 
@@ -321,12 +319,15 @@
 	c->private_data = s;
 
 	/* store input parameters in state structure */
-	s->io    = *io;
-	s->host  = talloc_strdup(c, io->binding->host);
-	s->port  = atoi(io->binding->endpoint);   /* port number is a binding endpoint here */
+	s->io               = *io;
+	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->port);
+	pipe_req = dcerpc_pipe_open_tcp_send(s->io.pipe->conn, s->host, s->target_hostname, 
+					     s->port);
 	composite_continue(c, pipe_req, continue_pipe_open_ncacn_ip_tcp, c);
 	return c;
 }
@@ -822,10 +823,11 @@
 	
 	status = composite_wait(c);
 	
-	s = talloc_get_type(c->private_data, struct pipe_connect_state);
-	talloc_steal(mem_ctx, s->pipe);
-	*p = s->pipe;
-
+	if (NT_STATUS_IS_OK(status)) {
+		s = talloc_get_type(c->private_data, struct pipe_connect_state);
+		talloc_steal(mem_ctx, s->pipe);
+		*p = s->pipe;
+	}
 	talloc_free(c);
 	return status;
 }
@@ -864,7 +866,6 @@
   The string is to be parsed to a binding structure first.
 */
 struct composite_context* dcerpc_pipe_connect_send(TALLOC_CTX *parent_ctx,
-						   struct dcerpc_pipe **pp,
 						   const char *binding,
 						   const struct dcerpc_interface_table *table,
 						   struct cli_credentials *credentials,
@@ -966,7 +967,8 @@
 			     struct event_context *ev)
 {
 	struct composite_context *c;
-	c = dcerpc_pipe_connect_send(parent_ctx, pp, binding, table,
+	c = dcerpc_pipe_connect_send(parent_ctx, binding, 
+				     table,
 				     credentials, ev);
 	return dcerpc_pipe_connect_recv(c, parent_ctx, pp);
 }
@@ -1032,6 +1034,7 @@
 	case NCACN_IP_TCP:
 		pipe_tcp_req = dcerpc_pipe_open_tcp_send(s->pipe2->conn,
 							 s->binding->host,
+							 s->binding->target_hostname,
 							 atoi(s->binding->endpoint));
 		composite_continue(c, pipe_tcp_req, continue_open_tcp, c);
 		return c;

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc_sock.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc_sock.c	2006-10-13 12:54:13 UTC (rev 19265)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc_sock.c	2006-10-13 13:01:48 UTC (rev 19266)
@@ -206,6 +206,7 @@
 	struct socket_context *socket_ctx;
 	struct sock_private *sock;
 	struct socket_address *server;
+	const char *target_hostname;
 	enum dcerpc_transport_t transport;
 };
 
@@ -248,7 +249,7 @@
 
 	sock->sock          = s->socket_ctx;
 	sock->pending_reads = 0;
-	sock->server_name   = strupper_talloc(sock, s->server->addr);
+	sock->server_name   = strupper_talloc(sock, s->target_hostname);
 
 	sock->fde = event_add_fd(conn->event_ctx, sock->sock, socket_get_fd(sock->sock),
 				 0, sock_io_handler, conn);
@@ -283,6 +284,7 @@
 struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ctx,
 						       struct dcerpc_connection *cn,
 						       struct socket_address *server,
+						       const char *target_hostname,
 						       enum dcerpc_transport_t transport)
 {
 	struct composite_context *c;
@@ -300,6 +302,7 @@
 	s->transport = transport;
 	s->server    = talloc_reference(c, server);
 	if (composite_nomem(s->server, c)) return c;
+	s->target_hostname = talloc_reference(s, target_hostname);
 
 	s->sock = talloc(cn, struct sock_private);
 	if (composite_nomem(s->sock, c)) return c;
@@ -328,17 +331,19 @@
 */
 NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_connection *conn,
 				 struct socket_address *server,
+				 const char *target_hostname,
 				 enum dcerpc_transport_t transport)
 {
 	struct composite_context *c;
 	
-	c = dcerpc_pipe_open_socket_send(conn, conn, server, transport);
+	c = dcerpc_pipe_open_socket_send(conn, conn, server, target_hostname, transport);
 	return dcerpc_pipe_open_socket_recv(c);
 }
 
 
 struct pipe_tcp_state {
-	const char *server;
+	const char *target_hostname;
+	const char *address;
 	uint32_t port;
 	struct socket_address *srvaddr;
 	struct dcerpc_connection *conn;
@@ -371,11 +376,13 @@
 	talloc_free(s->srvaddr);
 
 	/* prepare server address using host:ip and transport name */
-	s->srvaddr = socket_address_from_strings(s->conn, "ipv4", s->server, s->port);
+	s->srvaddr = socket_address_from_strings(s->conn, "ipv4", s->address, s->port);
 	if (composite_nomem(s->srvaddr, c)) return;
 
 	/* try IPv4 if IPv6 fails */
-	sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->srvaddr, NCACN_IP_TCP);
+	sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, 
+						     s->srvaddr, s->target_hostname, 
+						     NCACN_IP_TCP);
 	composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c);
 }
 
@@ -395,8 +402,9 @@
 	c->status = dcerpc_pipe_open_socket_recv(ctx);
 	if (!NT_STATUS_IS_OK(c->status)) {
 		/* something went wrong... */
-		DEBUG(0, ("Failed to connect host %s on port %d - %s.\n",
-			  s->server, s->port, nt_errstr(c->status)));
+		DEBUG(0, ("Failed to connect host %s (%s) on port %d - %s.\n",
+			  s->address, s->target_hostname, 
+			  s->port, nt_errstr(c->status)));
 
 		composite_error(c, c->status);
 		return;
@@ -411,7 +419,9 @@
   tcp/ip transport
 */
 struct composite_context* dcerpc_pipe_open_tcp_send(struct dcerpc_connection *conn,
-						    const char* server, uint32_t port)
+						    const char *address, 
+						    const char *target_hostname,
+						    uint32_t port)
 {
 	struct composite_context *c;
 	struct composite_context *sock_ipv6_req;
@@ -426,16 +436,19 @@
 	c->private_data = s;
 
 	/* store input parameters in state structure */
-	s->server = talloc_strdup(c, server);
-	s->port   = port;
-	s->conn   = conn;
+	s->address         = talloc_strdup(c, address);
+	s->target_hostname = talloc_strdup(c, target_hostname);
+	s->port            = port;
+	s->conn            = conn;
 	
 	/* prepare server address using host ip:port and transport name */
-	s->srvaddr = socket_address_from_strings(s->conn, "ipv6", s->server, s->port);
+	s->srvaddr = socket_address_from_strings(s->conn, "ipv6", address, s->port);
 	if (composite_nomem(s->srvaddr, c)) return c;
 
 	/* try IPv6 first - send socket open request */
-	sock_ipv6_req = dcerpc_pipe_open_socket_send(c, s->conn, s->srvaddr, NCACN_IP_TCP);
+	sock_ipv6_req = dcerpc_pipe_open_socket_send(c, s->conn, 
+						     s->srvaddr, s->target_hostname,
+						     NCACN_IP_TCP);
 	composite_continue(c, sock_ipv6_req, continue_ipv6_open_socket, c);
 	return c;
 }
@@ -458,11 +471,12 @@
   Open rpc pipe on tcp/ip transport - sync version
 */
 NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_connection *conn, const char *server,
+			      const char *target_hostname,
 			      uint32_t port)
 {
 	struct composite_context *c;
 
-	c = dcerpc_pipe_open_tcp_send(conn, server, port);
+	c = dcerpc_pipe_open_tcp_send(conn, server, target_hostname, port);
 	return dcerpc_pipe_open_tcp_recv(c);
 }
 
@@ -521,7 +535,9 @@
 	if (composite_nomem(s->srvaddr, c)) return c;
 
 	/* send socket open request */
-	sock_unix_req = dcerpc_pipe_open_socket_send(c, s->conn, s->srvaddr, NCALRPC);
+	sock_unix_req = dcerpc_pipe_open_socket_send(c, s->conn, 
+						     s->srvaddr, NULL,
+						     NCALRPC);
 	composite_continue(c, sock_unix_req, continue_unix_open_socket, c);
 	return c;
 }
@@ -605,7 +621,7 @@
 	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, NCALRPC);
+	sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, s->srvaddr, NULL, NCALRPC);
 	composite_continue(c, sock_np_req, continue_np_open_socket, c);
 	return c;
 }

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c	2006-10-13 12:54:13 UTC (rev 19265)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c	2006-10-13 13:01:48 UTC (rev 19266)
@@ -358,11 +358,12 @@
 		b->host = talloc_strdup(b, s);
 		options = NULL;
 	}
-
 	if (!b->host) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	b->target_hostname = b->host;
+
 	b->options = NULL;
 	b->flags = 0;
 	b->endpoint = NULL;

Modified: branches/SAMBA_4_0/source/torture/rpc/async_bind.c
===================================================================
--- branches/SAMBA_4_0/source/torture/rpc/async_bind.c	2006-10-13 12:54:13 UTC (rev 19265)
+++ branches/SAMBA_4_0/source/torture/rpc/async_bind.c	2006-10-13 13:01:48 UTC (rev 19266)
@@ -78,7 +78,7 @@
 	/* send bind requests */
 	for (i = 0; i < torture_numasync; i++) {
 		table[i] = &dcerpc_table_lsarpc;
-		bind_req[i] = dcerpc_pipe_connect_send(mem_ctx, &pipe[i], binding_string,
+		bind_req[i] = dcerpc_pipe_connect_send(mem_ctx, binding_string,
 						       table[i], creds, evt_ctx);
 	}
 



More information about the samba-cvs mailing list