svn commit: samba r3164 - in branches/SAMBA_4_0/source: lib/registry/reg_backend_rpc librpc/idl librpc/rpc

jelmer at samba.org jelmer at samba.org
Sun Oct 24 16:31:01 GMT 2004


Author: jelmer
Date: 2004-10-24 16:31:00 +0000 (Sun, 24 Oct 2004)
New Revision: 3164

WebSVN: http://websvn.samba.org/websvn/changeset.php?rep=samba&path=/branches/SAMBA_4_0/source&rev=3164&nolog=1

Log:
Look up ncalrpc identifiers using the EPMAPPER. ncalrpc now works nicely :-) 
The various interface that support ncalrpc work nicely when tested 
with smbtorture and ncalrpc.

Running RPC-SAMR against local smbd here is slightly faster using ncalrpc:
ncalrpc: 		1.8 sec
ncacn_ip_tcp:	1.9 sec
ncacn_np:		2.5 sec


Modified:
   branches/SAMBA_4_0/source/lib/registry/reg_backend_rpc/reg_backend_rpc.c
   branches/SAMBA_4_0/source/librpc/idl/epmapper.idl
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/registry/reg_backend_rpc/reg_backend_rpc.c
===================================================================
--- branches/SAMBA_4_0/source/lib/registry/reg_backend_rpc/reg_backend_rpc.c	2004-10-24 15:48:19 UTC (rev 3163)
+++ branches/SAMBA_4_0/source/lib/registry/reg_backend_rpc/reg_backend_rpc.c	2004-10-24 16:31:00 UTC (rev 3164)
@@ -105,8 +105,13 @@
 	struct dcerpc_pipe *p;
 	int n;
 
-	if(!h->credentials || !h->location) return WERR_INVALID_PARAM;
+	if (!h->credentials) return WERR_INVALID_PARAM;
 
+	/* Default to local smbd if no connection is specified */
+	if (!h->location) {
+		h->location = talloc_strdup(mem_ctx, "ncalrpc:");
+	}
+
 	user = talloc_strdup(mem_ctx, h->credentials);
 	pass = strchr(user, '%');
 	if(pass) 

Modified: branches/SAMBA_4_0/source/librpc/idl/epmapper.idl
===================================================================
--- branches/SAMBA_4_0/source/librpc/idl/epmapper.idl	2004-10-24 15:48:19 UTC (rev 3163)
+++ branches/SAMBA_4_0/source/librpc/idl/epmapper.idl	2004-10-24 16:31:00 UTC (rev 3164)
@@ -36,6 +36,7 @@
 	const string NDR_GUID_VERSION = 2;
 
 	const uint32 EPMAPPER_PORT = 135;
+	const string EPMAPPER_IDENTIFIER = "EPMAPPER";
 
 	typedef struct {
 		GUID uuid;

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c	2004-10-24 15:48:19 UTC (rev 3163)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c	2004-10-24 16:31:00 UTC (rev 3164)
@@ -130,6 +130,100 @@
 	return NT_STATUS_OK;
 }
 
+NTSTATUS dcerpc_epm_map_ncalrpc(TALLOC_CTX *mem_ctx, 
+				 const char *uuid, uint_t version, const char **identifier)
+{
+	struct dcerpc_pipe *p;
+	NTSTATUS status;
+	struct epm_Map r;
+	struct policy_handle handle;
+	struct GUID guid;
+	struct epm_twr_t twr, *twr_r;
+
+	if (strcasecmp(uuid, DCERPC_EPMAPPER_UUID) == 0 ||
+	    strcasecmp(uuid, DCERPC_MGMT_UUID) == 0) {
+		/* don't lookup epmapper via epmapper! */
+		*identifier = talloc_strdup(mem_ctx, EPMAPPER_IDENTIFIER);
+		return NT_STATUS_OK;
+	}
+
+	status = dcerpc_pipe_open_pipe(&p, EPMAPPER_IDENTIFIER);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/* we can use the pipes memory context here as we will have a short
+	   lived connection */
+	status = dcerpc_bind_byuuid(p, p, 
+				    DCERPC_EPMAPPER_UUID,
+				    DCERPC_EPMAPPER_VERSION);
+	if (!NT_STATUS_IS_OK(status)) {
+		dcerpc_pipe_close(p);
+		return status;
+	}
+
+	ZERO_STRUCT(handle);
+	ZERO_STRUCT(guid);
+
+	twr.tower.num_floors = 4;
+	twr.tower.floors = talloc(p, sizeof(twr.tower.floors[0]) * 5);
+
+	twr.tower.floors[0].lhs.protocol = EPM_PROTOCOL_UUID;
+	GUID_from_string(uuid, &twr.tower.floors[0].lhs.info.uuid.uuid);
+	twr.tower.floors[0].lhs.info.uuid.version = version;
+	twr.tower.floors[0].rhs.uuid.unknown = 0;
+
+	twr.tower.floors[1].lhs.protocol = EPM_PROTOCOL_UUID;
+	GUID_from_string(NDR_GUID, &twr.tower.floors[1].lhs.info.uuid.uuid);
+	twr.tower.floors[1].lhs.info.uuid.version = NDR_GUID_VERSION;
+	twr.tower.floors[1].rhs.uuid.unknown = 0;
+
+	twr.tower.floors[2].lhs.protocol = EPM_PROTOCOL_NCALRPC;
+	twr.tower.floors[2].lhs.info.lhs_data = data_blob(NULL, 0);
+	twr.tower.floors[2].rhs.ncalrpc.minor_version = 0;
+
+	twr.tower.floors[3].lhs.protocol = EPM_PROTOCOL_PIPE;
+	twr.tower.floors[3].lhs.info.lhs_data = data_blob(NULL, 0);
+	twr.tower.floors[3].rhs.pipe.path = talloc_strdup(p, "");
+
+	/* with some nice pretty paper around it of course */
+	r.in.object = &guid;
+	r.in.map_tower = &twr;
+	r.in.entry_handle = &handle;
+	r.in.max_towers = 1;
+	r.out.entry_handle = &handle;
+
+	status = dcerpc_epm_Map(p, p, &r);
+	if (!NT_STATUS_IS_OK(status)) {
+		dcerpc_pipe_close(p);
+		return status;
+	}
+	if (r.out.result != 0 || r.out.num_towers != 1) {
+		dcerpc_pipe_close(p);
+		return NT_STATUS_PORT_UNREACHABLE;
+	}
+
+	twr_r = r.out.towers[0].twr;
+	if (!twr_r) {
+		dcerpc_pipe_close(p);
+		return NT_STATUS_PORT_UNREACHABLE;
+	}
+
+	if (twr_r->tower.num_floors != 4 ||
+	    twr_r->tower.floors[3].lhs.protocol != twr.tower.floors[3].lhs.protocol) {
+		dcerpc_pipe_close(p);
+		return NT_STATUS_PORT_UNREACHABLE;
+	}
+
+	*identifier = talloc_strdup(mem_ctx, twr_r->tower.floors[3].rhs.pipe.path);
+
+	dcerpc_pipe_close(p);
+
+	return NT_STATUS_OK;
+}
+
+
+
 /*
   find the pipe name for a local IDL interface
 */
@@ -858,18 +952,32 @@
 						 const char *password)
 {
 	NTSTATUS status;
+	const char *identifier = NULL;
+	TALLOC_CTX *mem_ctx = talloc_init("dcerpc_pipe_connect_ncalrpc");
 
-	/* FIXME: Look up identifier using the epmapper */
-	if (!binding->options || !binding->options[0]) {
-		DEBUG(0, ("Identifier not specified\n"));
-		return NT_STATUS_INVALID_PARAMETER;
+	if (binding->options) {
+		identifier = binding->options[0];
 	}
 
-	status = dcerpc_pipe_open_pipe(p, binding->options[0]);
+	/* Look up identifier using the epmapper */
+	if (!identifier) {
+		status = dcerpc_epm_map_ncalrpc(mem_ctx, pipe_uuid, pipe_version,
+						 &identifier);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0,("Failed to map DCERPC/TCP NCALRPC identifier for '%s' - %s\n", 
+				 pipe_uuid, nt_errstr(status)));
+			talloc_destroy(mem_ctx);
+			return status;
+		}
+		DEBUG(1,("Mapped to DCERPC/TCP identifier %s\n", identifier));
+	}
 
+	status = dcerpc_pipe_open_pipe(p, identifier);
+
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0,("Failed to open ncalrpc pipe '%s'\n", binding->options[0]));
-                return status;
+		DEBUG(0,("Failed to open ncalrpc pipe '%s'\n", identifier));
+		talloc_destroy(mem_ctx);
+   		return status;
     }
 
 	(*p)->flags = binding->flags;
@@ -891,9 +999,11 @@
 			 pipe_uuid, nt_errstr(status)));
 		dcerpc_pipe_close(*p);
 		*p = NULL;
+		talloc_destroy(mem_ctx);
 		return status;
 	}
  
+	talloc_destroy(mem_ctx);
     return status;
 }
 
@@ -911,7 +1021,6 @@
 {
 	NTSTATUS status;
 
-	/* FIXME: Look up path via the epmapper */
 	if (!binding->options || !binding->options[0]) {
 		DEBUG(0, ("Path to unix socket not specified\n"));
 		return NT_STATUS_INVALID_PARAMETER;



More information about the samba-cvs mailing list