mirror of
https://github.com/samba-team/samba.git
synced 2025-03-11 16:58:40 +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 used to be commit 2cfc8f24ce209f47153d3a5bd7007dd1b0578b26)
This commit is contained in:
parent
78e5bc76b6
commit
b9956de1b1
@ -105,7 +105,12 @@ static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct
|
|||||||
struct dcerpc_pipe *p;
|
struct dcerpc_pipe *p;
|
||||||
int n;
|
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);
|
user = talloc_strdup(mem_ctx, h->credentials);
|
||||||
pass = strchr(user, '%');
|
pass = strchr(user, '%');
|
||||||
|
@ -36,6 +36,7 @@ interface epmapper
|
|||||||
const string NDR_GUID_VERSION = 2;
|
const string NDR_GUID_VERSION = 2;
|
||||||
|
|
||||||
const uint32 EPMAPPER_PORT = 135;
|
const uint32 EPMAPPER_PORT = 135;
|
||||||
|
const string EPMAPPER_IDENTIFIER = "EPMAPPER";
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GUID uuid;
|
GUID uuid;
|
||||||
|
@ -130,6 +130,100 @@ NTSTATUS dcerpc_epm_map_tcp_port(const char *server,
|
|||||||
return NT_STATUS_OK;
|
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
|
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)
|
const char *password)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
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) {
|
||||||
if (!binding->options || !binding->options[0]) {
|
identifier = binding->options[0];
|
||||||
DEBUG(0, ("Identifier not specified\n"));
|
|
||||||
return NT_STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(0,("Failed to open ncalrpc pipe '%s'\n", binding->options[0]));
|
DEBUG(0,("Failed to open ncalrpc pipe '%s'\n", identifier));
|
||||||
return status;
|
talloc_destroy(mem_ctx);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*p)->flags = binding->flags;
|
(*p)->flags = binding->flags;
|
||||||
@ -891,9 +999,11 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p,
|
|||||||
pipe_uuid, nt_errstr(status)));
|
pipe_uuid, nt_errstr(status)));
|
||||||
dcerpc_pipe_close(*p);
|
dcerpc_pipe_close(*p);
|
||||||
*p = NULL;
|
*p = NULL;
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,7 +1021,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **p,
|
|||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
/* FIXME: Look up path via the epmapper */
|
|
||||||
if (!binding->options || !binding->options[0]) {
|
if (!binding->options || !binding->options[0]) {
|
||||||
DEBUG(0, ("Path to unix socket not specified\n"));
|
DEBUG(0, ("Path to unix socket not specified\n"));
|
||||||
return NT_STATUS_INVALID_PARAMETER;
|
return NT_STATUS_INVALID_PARAMETER;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user