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:
parent
426f3e63ca
commit
2cfc8f24ce
@ -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, '%');
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user