1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

r3164: 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
This commit is contained in:
Jelmer Vernooij 2004-10-24 16:31:00 +00:00 committed by Gerald (Jerry) Carter
parent 426f3e63ca
commit 2cfc8f24ce
3 changed files with 124 additions and 9 deletions

View File

@ -105,7 +105,12 @@ static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct
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, '%');

View File

@ -36,6 +36,7 @@ interface epmapper
const string NDR_GUID_VERSION = 2;
const uint32 EPMAPPER_PORT = 135;
const string EPMAPPER_IDENTIFIER = "EPMAPPER";
typedef struct {
GUID uuid;

View File

@ -130,6 +130,100 @@ NTSTATUS dcerpc_epm_map_tcp_port(const char *server,
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 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p,
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 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p,
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 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **p,
{
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;