mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
added the epm_Map() call.
the RPC-EPMAPPER torture test now passes
(This used to be commit fbdcf9ef54
)
This commit is contained in:
parent
340d9b71f9
commit
da86d3af31
@ -123,6 +123,8 @@ interface epmapper
|
||||
/**********************/
|
||||
/* Function 0x03 */
|
||||
|
||||
const int EPMAPPER_MAP_FAILED = 0x16c9a0d6;
|
||||
|
||||
typedef struct {
|
||||
epm_twr_t *twr;
|
||||
} epm_twr_p_t;
|
||||
|
@ -105,6 +105,7 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb,
|
||||
(*p)->ndr = NULL;
|
||||
(*p)->dispatch = NULL;
|
||||
(*p)->handles = NULL;
|
||||
(*p)->next_handle = 0;
|
||||
|
||||
/* make sure the endpoint server likes the connection */
|
||||
status = ops->connect(*p);
|
||||
|
@ -26,14 +26,104 @@
|
||||
/* handle types for this module */
|
||||
enum handle_types {HTYPE_LOOKUP};
|
||||
|
||||
|
||||
/*
|
||||
simple routine to compare a GUID string to a GUID structure
|
||||
*/
|
||||
static int guid_cmp(TALLOC_CTX *mem_ctx, const GUID *guid, const char *uuid_str)
|
||||
{
|
||||
const char *s = GUID_string(mem_ctx, guid);
|
||||
if (!s || strcasecmp(s, uuid_str)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
fill a protocol tower
|
||||
*/
|
||||
static BOOL fill_protocol_tower(TALLOC_CTX *mem_ctx, struct epm_towers *twr,
|
||||
struct dcesrv_ep_iface *e)
|
||||
{
|
||||
twr->num_floors = 5;
|
||||
twr->floors = talloc_array_p(mem_ctx, struct epm_floor, 5);
|
||||
if (!twr->floors) {
|
||||
return False;
|
||||
}
|
||||
|
||||
twr->floors[0].lhs.protocol = EPM_PROTOCOL_UUID;
|
||||
GUID_from_string(e->uuid, &twr->floors[0].lhs.info.uuid.uuid);
|
||||
twr->floors[0].lhs.info.uuid.version = e->if_version;
|
||||
twr->floors[0].rhs.rhs_data = data_blob_talloc_zero(mem_ctx, 2);
|
||||
|
||||
/* encoded with NDR ... */
|
||||
twr->floors[1].lhs.protocol = EPM_PROTOCOL_UUID;
|
||||
GUID_from_string(NDR_GUID, &twr->floors[1].lhs.info.uuid.uuid);
|
||||
twr->floors[1].lhs.info.uuid.version = NDR_GUID_VERSION;
|
||||
twr->floors[1].rhs.rhs_data = data_blob_talloc_zero(mem_ctx, 2);
|
||||
|
||||
/* on an RPC connection ... */
|
||||
twr->floors[2].lhs.protocol = EPM_PROTOCOL_RPC_C;
|
||||
twr->floors[2].lhs.info.lhs_data = data_blob(NULL, 0);
|
||||
twr->floors[2].rhs.rhs_data = data_blob_talloc_zero(mem_ctx, 2);
|
||||
|
||||
/* on a SMB pipe ... */
|
||||
twr->floors[3].lhs.protocol = EPM_PROTOCOL_SMB;
|
||||
twr->floors[3].lhs.info.lhs_data = data_blob(NULL, 0);
|
||||
twr->floors[3].rhs.rhs_data.data = talloc_asprintf(mem_ctx, "\\PIPE\\%s",
|
||||
e->endpoint.info.smb_pipe);
|
||||
twr->floors[3].rhs.rhs_data.length = strlen(twr->floors[3].rhs.rhs_data.data);
|
||||
|
||||
/* on an NetBIOS link ... */
|
||||
twr->floors[4].lhs.protocol = EPM_PROTOCOL_NETBIOS;
|
||||
twr->floors[4].lhs.info.lhs_data = data_blob(NULL, 0);
|
||||
twr->floors[4].rhs.rhs_data.data = talloc_asprintf(mem_ctx, "\\\\%s",
|
||||
lp_netbios_name());
|
||||
twr->floors[4].rhs.rhs_data.length = strlen(twr->floors[4].rhs.rhs_data.data);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
build a list of all interfaces handled by all endpoint servers
|
||||
*/
|
||||
static uint32 build_ep_list(TALLOC_CTX *mem_ctx,
|
||||
struct dce_endpoint *endpoint_list,
|
||||
struct dcesrv_ep_iface **eps)
|
||||
{
|
||||
struct dce_endpoint *d;
|
||||
uint32 total = 0;
|
||||
|
||||
(*eps) = NULL;
|
||||
|
||||
for (d=endpoint_list; d; d=d->next) {
|
||||
struct dcesrv_ep_iface *e;
|
||||
int count = d->endpoint_ops->lookup_endpoints(mem_ctx, &e);
|
||||
if (count > 0) {
|
||||
(*eps) = talloc_realloc_p(mem_ctx, *eps,
|
||||
struct dcesrv_ep_iface,
|
||||
total + count);
|
||||
if (!*eps) {
|
||||
return 0;
|
||||
}
|
||||
memcpy((*eps) + total, e, sizeof(*e) * count);
|
||||
total += count;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS epm_Insert(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
struct epm_Lookup *r)
|
||||
struct epm_Insert *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS epm_Delete(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
struct epm_Lookup *r)
|
||||
struct epm_Delete *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -64,31 +154,13 @@ static NTSTATUS epm_Lookup(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
if (!eps) {
|
||||
/* this is the first call - fill the list. Subsequent calls
|
||||
will feed from this list, stored in the handle */
|
||||
struct dce_endpoint *d;
|
||||
struct dcesrv_ep_iface *e;
|
||||
|
||||
eps = talloc_p(h->mem_ctx, struct rpc_eps);
|
||||
if (!eps) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
eps->count = 0;
|
||||
eps->e = NULL;
|
||||
h->data = eps;
|
||||
|
||||
for (d=dce->smb->dcesrv.endpoint_list; d; d=d->next) {
|
||||
int count = d->endpoint_ops->lookup_endpoints(h->mem_ctx, &e);
|
||||
if (count > 0) {
|
||||
eps->e = talloc_realloc_p(h->mem_ctx,
|
||||
eps->e,
|
||||
struct dcesrv_ep_iface,
|
||||
eps->count + count);
|
||||
if (!eps->e) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
memcpy(eps->e + eps->count, e, sizeof(*e) * count);
|
||||
eps->count += count;
|
||||
}
|
||||
}
|
||||
|
||||
eps->count = build_ep_list(h->mem_ctx, dce->smb->dcesrv.endpoint_list, &eps->e);
|
||||
}
|
||||
|
||||
/* return the next N elements */
|
||||
@ -112,52 +184,16 @@ static NTSTATUS epm_Lookup(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
for (i=0;i<num_ents;i++) {
|
||||
struct epm_twr_t *t;
|
||||
struct epm_towers *twr;
|
||||
|
||||
ZERO_STRUCT(r->out.entries[i].object);
|
||||
r->out.entries[i].annotation = "";
|
||||
t = talloc_p(mem_ctx, struct epm_twr_t);
|
||||
if (!twr) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
r->out.entries[i].tower = t;
|
||||
twr = &t->towers;
|
||||
twr->num_floors = 5;
|
||||
twr->floors = talloc_array_p(mem_ctx, struct epm_floor, 5);
|
||||
if (!twr->floors) {
|
||||
r->out.entries[i].tower = talloc_p(mem_ctx, struct epm_twr_t);
|
||||
if (!r->out.entries[i].tower) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
twr->floors[0].lhs.protocol = EPM_PROTOCOL_UUID;
|
||||
GUID_from_string(eps->e[i].uuid, &twr->floors[0].lhs.info.uuid.uuid);
|
||||
twr->floors[0].lhs.info.uuid.version = eps->e[i].if_version;
|
||||
twr->floors[0].rhs.rhs_data = data_blob_talloc_zero(mem_ctx, 2);
|
||||
|
||||
/* encoded with NDR ... */
|
||||
twr->floors[1].lhs.protocol = EPM_PROTOCOL_UUID;
|
||||
GUID_from_string(NDR_GUID, &twr->floors[1].lhs.info.uuid.uuid);
|
||||
twr->floors[1].lhs.info.uuid.version = NDR_GUID_VERSION;
|
||||
twr->floors[1].rhs.rhs_data = data_blob_talloc_zero(mem_ctx, 2);
|
||||
|
||||
/* on an RPC connection ... */
|
||||
twr->floors[2].lhs.protocol = EPM_PROTOCOL_RPC_C;
|
||||
twr->floors[2].lhs.info.lhs_data = data_blob(NULL, 0);
|
||||
twr->floors[2].rhs.rhs_data = data_blob_talloc_zero(mem_ctx, 2);
|
||||
|
||||
/* on a SMB pipe ... */
|
||||
twr->floors[3].lhs.protocol = EPM_PROTOCOL_SMB;
|
||||
twr->floors[3].lhs.info.lhs_data = data_blob(NULL, 0);
|
||||
twr->floors[3].rhs.rhs_data.data = talloc_asprintf(mem_ctx, "\\PIPE\\%s",
|
||||
eps->e[i].endpoint.info.smb_pipe);
|
||||
twr->floors[3].rhs.rhs_data.length = strlen(twr->floors[3].rhs.rhs_data.data);
|
||||
|
||||
/* on an NetBIOS link ... */
|
||||
twr->floors[4].lhs.protocol = EPM_PROTOCOL_NETBIOS;
|
||||
twr->floors[4].lhs.info.lhs_data = data_blob(NULL, 0);
|
||||
twr->floors[4].rhs.rhs_data.data = talloc_asprintf(mem_ctx, "\\\\%s",
|
||||
lp_netbios_name());
|
||||
twr->floors[4].rhs.rhs_data.length = strlen(twr->floors[4].rhs.rhs_data.data);
|
||||
if (!fill_protocol_tower(mem_ctx, &r->out.entries[i].tower->towers, &eps->e[i])) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
eps->count -= num_ents;
|
||||
@ -172,25 +208,88 @@ static NTSTATUS epm_Lookup(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
a generic protocol tower
|
||||
*/
|
||||
static NTSTATUS epm_Map(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
struct epm_Lookup *r)
|
||||
struct epm_Map *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
uint32 count;
|
||||
int i;
|
||||
struct dcesrv_ep_iface *eps;
|
||||
struct epm_floor *floors;
|
||||
|
||||
count = build_ep_list(mem_ctx, dce->smb->dcesrv.endpoint_list, &eps);
|
||||
|
||||
ZERO_STRUCTP(r->out.entry_handle);
|
||||
r->out.num_towers = 1;
|
||||
r->out.status = 0;
|
||||
r->out.towers = talloc_p(mem_ctx, struct epm_twr_p_t);
|
||||
if (!r->out.towers) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
r->out.towers->twr = talloc_p(mem_ctx, struct epm_twr_t);
|
||||
if (!r->out.towers->twr) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (!r->in.map_tower || r->in.max_towers == 0 ||
|
||||
r->in.map_tower->towers.num_floors != 5) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
floors = r->in.map_tower->towers.floors;
|
||||
|
||||
if (floors[0].lhs.protocol != EPM_PROTOCOL_UUID ||
|
||||
floors[1].lhs.protocol != EPM_PROTOCOL_UUID ||
|
||||
guid_cmp(mem_ctx, &floors[1].lhs.info.uuid.uuid, NDR_GUID) != 0 ||
|
||||
floors[1].lhs.info.uuid.version != NDR_GUID_VERSION ||
|
||||
floors[2].lhs.protocol != EPM_PROTOCOL_RPC_C) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
if (guid_cmp(mem_ctx, &floors[0].lhs.info.uuid.uuid, eps[i].uuid) != 0 ||
|
||||
floors[0].lhs.info.uuid.version != eps[i].if_version) {
|
||||
continue;
|
||||
}
|
||||
switch (eps[i].endpoint.type) {
|
||||
case ENDPOINT_SMB:
|
||||
if (floors[3].lhs.protocol != EPM_PROTOCOL_SMB ||
|
||||
floors[4].lhs.protocol != EPM_PROTOCOL_NETBIOS) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ENDPOINT_TCP:
|
||||
if (floors[3].lhs.protocol != EPM_PROTOCOL_TCP ||
|
||||
floors[4].lhs.protocol != EPM_PROTOCOL_IP) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fill_protocol_tower(mem_ctx, &r->out.towers->twr->towers, &eps[i]);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
failed:
|
||||
r->out.num_towers = 0;
|
||||
r->out.status = EPMAPPER_MAP_FAILED;
|
||||
r->out.towers->twr = NULL;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS epm_LookupHandleFree(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
struct epm_Lookup *r)
|
||||
struct epm_LookupHandleFree *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS epm_InqObject(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
struct epm_Lookup *r)
|
||||
struct epm_InqObject *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS epm_MgmtDelete(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
|
||||
struct epm_Lookup *r)
|
||||
struct epm_MgmtDelete *r)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_state *dce,
|
||||
|
||||
/* TODO: check for wraparound here */
|
||||
SIVAL(&h->wire_handle.data, 12, random());
|
||||
SIVAL(&h->wire_handle.data, 16, dce->next_handle);
|
||||
dce->next_handle++;
|
||||
SIVAL(&h->wire_handle.data, 16, dce->next_handle);
|
||||
|
||||
DLIST_ADD(dce->handles, h);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user