summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/idl/epmapper.idl5
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c63
-rw-r--r--source4/rpc_server/dcerpc_server.c1
-rw-r--r--source4/rpc_server/dcerpc_server.h1
-rw-r--r--source4/rpc_server/epmapper/rpc_epmapper.c11
5 files changed, 68 insertions, 13 deletions
diff --git a/source4/librpc/idl/epmapper.idl b/source4/librpc/idl/epmapper.idl
index 59c542255d..79fb7f3dd1 100644
--- a/source4/librpc/idl/epmapper.idl
+++ b/source4/librpc/idl/epmapper.idl
@@ -20,6 +20,9 @@ interface epmapper
with.
*/
+ const int EPMAPPER_STATUS_NO_MORE_ENTRIES = 0x16c9a0d6;
+
+
/* this guid indicates NDR encoding in a protocol tower */
const string NDR_GUID = "8a885d04-1ceb-11c9-9fe8-08002b104860";
const string NDR_GUID_VERSION = 2;
@@ -123,8 +126,6 @@ interface epmapper
/**********************/
/* Function 0x03 */
- const int EPMAPPER_MAP_FAILED = 0x16c9a0d6;
-
typedef struct {
epm_twr_t *twr;
} epm_twr_p_t;
diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c
index b57e72f14a..04825ec632 100644
--- a/source4/ntvfs/ipc/vfs_ipc.c
+++ b/source4/ntvfs/ipc/vfs_ipc.c
@@ -40,6 +40,7 @@ struct ipc_private {
const char *pipe_name;
uint16 fnum;
struct dcesrv_state *pipe_state;
+ uint16 ipc_state;
} *pipe_list;
};
@@ -223,6 +224,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
while (p->pipe_name[0] == '\\') {
p->pipe_name++;
}
+ p->ipc_state = 0x5ff;
/*
we're all set, now ask the dcerpc server subsystem to open the
@@ -250,6 +252,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi)
ZERO_STRUCT(oi->ntcreatex.out);
oi->ntcreatex.out.fnum = p->fnum;
+ oi->ntcreatex.out.ipc_state = p->ipc_state;
return NT_STATUS_OK;
}
@@ -508,17 +511,12 @@ NTSTATUS ipc_search_close(struct request_context *req, union smb_search_close *i
}
-/* SMBtrans - used to provide access to SMB pipes */
-static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans)
+/* SMBtrans - handle a DCERPC command */
+static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *trans)
{
struct pipe_state *p;
struct ipc_private *private = req->conn->ntvfs_private;
NTSTATUS status;
-
- if (trans->in.setup_count != 2 ||
- trans->in.setup[0] != TRANSACT_DCERPCCMD) {
- return NT_STATUS_INVALID_PARAMETER;
- }
/* the fnum is in setup[1] */
p = pipe_state_find(private, trans->in.setup[1]);
@@ -558,6 +556,57 @@ static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans)
}
+/* SMBtrans - set named pipe state */
+static NTSTATUS ipc_set_nm_pipe_state(struct request_context *req, struct smb_trans2 *trans)
+{
+ struct pipe_state *p;
+ struct ipc_private *private = req->conn->ntvfs_private;
+
+ /* the fnum is in setup[1] */
+ p = pipe_state_find(private, trans->in.setup[1]);
+ if (!p) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (trans->in.params.length != 2) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ p->ipc_state = SVAL(trans->in.params.data, 0);
+
+ trans->out.setup_count = 0;
+ trans->out.setup = NULL;
+ trans->out.params = data_blob(NULL, 0);
+ trans->out.data = data_blob(NULL, 0);
+
+ return NT_STATUS_OK;
+}
+
+
+/* SMBtrans - used to provide access to SMB pipes */
+static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans)
+{
+ NTSTATUS status;
+
+ if (trans->in.setup_count != 2) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ switch (trans->in.setup[0]) {
+ case TRANSACT_SETNAMEDPIPEHANDLESTATE:
+ status = ipc_set_nm_pipe_state(req, trans);
+ break;
+ case TRANSACT_DCERPCCMD:
+ status = ipc_dcerpc_cmd(req, trans);
+ break;
+ default:
+ status = NT_STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return status;
+}
+
+
/*
initialialise the IPC backend, registering ourselves with the ntvfs subsystem
diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c
index 35661d913e..67b36cdc48 100644
--- a/source4/rpc_server/dcerpc_server.c
+++ b/source4/rpc_server/dcerpc_server.c
@@ -651,6 +651,7 @@ int dcesrv_lookup_endpoints(const struct dcerpc_interface_table *table,
return -1;
}
+ (*e)->name = table->name;
(*e)->uuid = table->uuid;
(*e)->if_version = table->if_version;
(*e)->endpoint.type = ENDPOINT_SMB;
diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h
index 3f2f5d039f..83e0ee249a 100644
--- a/source4/rpc_server/dcerpc_server.h
+++ b/source4/rpc_server/dcerpc_server.h
@@ -35,6 +35,7 @@ struct dcesrv_endpoint {
/* a endpoint combined with an interface description */
struct dcesrv_ep_iface {
+ const char *name;
struct dcesrv_endpoint endpoint;
const char *uuid;
uint32 if_version;
diff --git a/source4/rpc_server/epmapper/rpc_epmapper.c b/source4/rpc_server/epmapper/rpc_epmapper.c
index c5bd2ffa45..2898a70159 100644
--- a/source4/rpc_server/epmapper/rpc_epmapper.c
+++ b/source4/rpc_server/epmapper/rpc_epmapper.c
@@ -72,14 +72,14 @@ static BOOL fill_protocol_tower(TALLOC_CTX *mem_ctx, struct epm_towers *twr,
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);
+ twr->floors[3].rhs.rhs_data.length = strlen(twr->floors[3].rhs.rhs_data.data)+1;
/* 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);
+ twr->floors[4].rhs.rhs_data.length = strlen(twr->floors[4].rhs.rhs_data.data)+1;
return True;
}
@@ -175,6 +175,9 @@ static NTSTATUS epm_Lookup(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
if (num_ents == 0) {
r->out.entries = NULL;
+ r->out.status = EPMAPPER_STATUS_NO_MORE_ENTRIES;
+ ZERO_STRUCTP(r->out.entry_handle);
+ dcesrv_handle_destroy(dce, h);
return NT_STATUS_OK;
}
@@ -185,7 +188,7 @@ static NTSTATUS epm_Lookup(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
for (i=0;i<num_ents;i++) {
ZERO_STRUCT(r->out.entries[i].object);
- r->out.entries[i].annotation = "";
+ r->out.entries[i].annotation = eps->e[i].name;
r->out.entries[i].tower = talloc_p(mem_ctx, struct epm_twr_t);
if (!r->out.entries[i].tower) {
return NT_STATUS_NO_MEMORY;
@@ -270,7 +273,7 @@ static NTSTATUS epm_Map(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx,
failed:
r->out.num_towers = 0;
- r->out.status = EPMAPPER_MAP_FAILED;
+ r->out.status = EPMAPPER_STATUS_NO_MORE_ENTRIES;
r->out.towers->twr = NULL;
return NT_STATUS_OK;