summaryrefslogtreecommitdiff
path: root/source4/ntvfs/ipc
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2006-05-20 08:15:22 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:08:10 -0500
commit9ef33f5f5c786b83311ca088357fb2f0aa72fc9e (patch)
tree66335dced1641119f94e6c656dd1ccc673218d0c /source4/ntvfs/ipc
parent0dcecc314899b6f36e9215e0b3881220062ba4f9 (diff)
downloadsamba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.tar.gz
samba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.tar.bz2
samba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.zip
r15734: This is a major change to the NTVFS subsystem:
- to use a struct ntvfs_handle instead of a uint16_t fnum. (to make it independend from the frontend protocol) - the allocation of handles now is provided by the frontend (smbsrv_*) via callbacks and not by each backend module - this also makes sure that file handles are only passed to the ntvfs subsystem when the tcon and session matches, so modules can rely on this and need to check this. - this allows multiple modules in the ntvfs module chain to allocate file handles. This can be used for virtual files like "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION"... - also this will make SMB2 with 128 bit file handles possible metze (This used to be commit 287fc1c22d670f6e568014b420f7f4cb31dc7958)
Diffstat (limited to 'source4/ntvfs/ipc')
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c106
1 files changed, 47 insertions, 59 deletions
diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c
index 6ef380c4eb..fdad41145b 100644
--- a/source4/ntvfs/ipc/vfs_ipc.c
+++ b/source4/ntvfs/ipc/vfs_ipc.c
@@ -32,16 +32,12 @@
#include "ntvfs/ipc/proto.h"
#include "rpc_server/dcerpc_server.h"
-#define IPC_BASE_FNUM 0x400
-
/* this is the private structure used to keep the state of an open
ipc$ connection. It needs to keep information about all open
pipes */
struct ipc_private {
struct ntvfs_module_context *ntvfs;
- struct idr_context *idtree_fnum;
-
struct dcesrv_context *dcesrv;
/* a list of open pipes */
@@ -49,41 +45,43 @@ struct ipc_private {
struct pipe_state *next, *prev;
struct ipc_private *private;
const char *pipe_name;
- uint16_t fnum;
+ struct ntvfs_handle *handle;
struct dcesrv_connection *dce_conn;
uint16_t ipc_state;
- /* we need to remember the session it was opened on,
- as it is illegal to operate on someone elses fnum */
- struct auth_session_info *session_info;
-
- /* we need to remember the client pid that
- opened the file so SMBexit works */
- uint16_t smbpid;
} *pipe_list;
};
/*
- find a open pipe give a file descriptor
+ find a open pipe give a file handle
*/
-static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t fnum,
- struct auth_session_info *session_info)
+static struct pipe_state *pipe_state_find(struct ipc_private *private, struct ntvfs_handle *handle)
{
struct pipe_state *s;
void *p;
- p = idr_find(private->idtree_fnum, fnum);
+ p = ntvfs_handle_get_backend_data(handle, private->ntvfs);
if (!p) return NULL;
s = talloc_get_type(p, struct pipe_state);
-
- if (s->session_info != session_info) {
- return NULL;
- }
+ if (!s) return NULL;
return s;
}
+/*
+ find a open pipe give a wire fnum
+*/
+static struct pipe_state *pipe_state_find_key(struct ipc_private *private, struct ntvfs_request *req, const DATA_BLOB *key)
+{
+ struct ntvfs_handle *h;
+
+ h = ntvfs_handle_search_by_wire_key(private->ntvfs, req, key);
+ if (!h) return NULL;
+
+ return pipe_state_find(private, h);
+}
+
/*
connect to a share - always works
@@ -109,9 +107,6 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs,
private->ntvfs = ntvfs;
private->pipe_list = NULL;
- private->idtree_fnum = idr_init(private);
- NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum);
-
/* setup the DCERPC server subsystem */
status = dcesrv_init_ipc_context(private, &private->dcesrv);
NT_STATUS_NOT_OK_RETURN(status);
@@ -182,7 +177,6 @@ static NTSTATUS ipc_setpathinfo(struct ntvfs_module_context *ntvfs,
static int ipc_fd_destructor(void *ptr)
{
struct pipe_state *p = ptr;
- idr_remove(p->private->idtree_fnum, p->fnum);
DLIST_REMOVE(p->private->pipe_list, p);
return 0;
}
@@ -212,9 +206,12 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
NTSTATUS status;
struct dcerpc_binding *ep_description;
struct ipc_private *private = ntvfs->private_data;
- int fnum;
+ struct ntvfs_handle *h;
+
+ status = ntvfs_handle_new(ntvfs, req, &h);
+ NT_STATUS_NOT_OK_RETURN(status);
- p = talloc(req, struct pipe_state);
+ p = talloc(h, struct pipe_state);
NT_STATUS_HAVE_NO_MEMORY(p);
ep_description = talloc(req, struct dcerpc_binding);
@@ -225,12 +222,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname);
NT_STATUS_HAVE_NO_MEMORY(p->pipe_name);
- fnum = idr_get_new_above(private->idtree_fnum, p, IPC_BASE_FNUM, UINT16_MAX);
- if (fnum == -1) {
- return NT_STATUS_TOO_MANY_OPENED_FILES;
- }
-
- p->fnum = fnum;
+ p->handle = h;
p->ipc_state = 0x5ff;
/*
@@ -248,14 +240,11 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
status = dcesrv_endpoint_search_connect(private->dcesrv,
p,
ep_description,
- req->session_info,
+ h->session_info,
ntvfs->ctx->event_ctx,
0,
&p->dce_conn);
- if (!NT_STATUS_IS_OK(status)) {
- idr_remove(private->idtree_fnum, p->fnum);
- return status;
- }
+ NT_STATUS_NOT_OK_RETURN(status);
p->dce_conn->transport.private_data = private;
p->dce_conn->transport.report_output_data = NULL;
@@ -264,16 +253,14 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
DLIST_ADD(private->pipe_list, p);
- p->smbpid = req->smbpid;
- p->session_info = req->session_info;
p->private = private;
- *ps = p;
-
- talloc_steal(private, p);
-
talloc_set_destructor(p, ipc_fd_destructor);
+ status = ntvfs_handle_set_backend_data(h, private->ntvfs, p);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ *ps = p;
return NT_STATUS_OK;
}
@@ -292,7 +279,7 @@ static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs,
}
ZERO_STRUCT(oi->ntcreatex.out);
- oi->ntcreatex.out.file.fnum = p->fnum;
+ oi->ntcreatex.out.file.ntvfs= p->handle;
oi->ntcreatex.out.ipc_state = p->ipc_state;
oi->ntcreatex.out.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
@@ -315,7 +302,7 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs,
}
ZERO_STRUCT(oi->openx.out);
- oi->openx.out.file.fnum = p->fnum;
+ oi->openx.out.file.ntvfs= p->handle;
oi->openx.out.ftype = 2;
oi->openx.out.devstate = p->ipc_state;
@@ -401,7 +388,6 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs,
{
struct ipc_private *private = ntvfs->private_data;
DATA_BLOB data;
- uint16_t fnum;
struct pipe_state *p;
NTSTATUS status = NT_STATUS_OK;
@@ -409,9 +395,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs,
return ntvfs_map_read(ntvfs, req, rd);
}
- fnum = rd->readx.in.file.fnum;
-
- p = pipe_state_find(private, fnum, req->session_info);
+ p = pipe_state_find(private, rd->readx.in.file.ntvfs);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -444,7 +428,6 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs,
{
struct ipc_private *private = ntvfs->private_data;
DATA_BLOB data;
- uint16_t fnum;
struct pipe_state *p;
NTSTATUS status;
@@ -452,11 +435,10 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs,
return ntvfs_map_write(ntvfs, req, wr);
}
- fnum = wr->writex.in.file.fnum;
data.data = discard_const_p(void, wr->writex.in.data);
data.length = wr->writex.in.count;
- p = pipe_state_find(private, fnum, req->session_info);
+ p = pipe_state_find(private, wr->writex.in.file.ntvfs);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -505,7 +487,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs,
return ntvfs_map_close(ntvfs, req, io);
}
- p = pipe_state_find(private, io->close.in.file.fnum, req->session_info);
+ p = pipe_state_find(private, io->close.in.file.ntvfs);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -526,8 +508,8 @@ static NTSTATUS ipc_exit(struct ntvfs_module_context *ntvfs,
for (p=private->pipe_list; p; p=next) {
next = p->next;
- if (p->session_info == req->session_info &&
- p->smbpid == req->smbpid) {
+ if (p->handle->session_info == req->session_info &&
+ p->handle->smbpid == req->smbpid) {
talloc_free(p);
}
}
@@ -546,7 +528,7 @@ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs,
for (p=private->pipe_list; p; p=next) {
next = p->next;
- if (p->session_info == req->session_info) {
+ if (p->handle->session_info == req->session_info) {
talloc_free(p);
}
}
@@ -674,9 +656,12 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs,
struct pipe_state *p;
struct ipc_private *private = ntvfs->private_data;
NTSTATUS status;
+ DATA_BLOB fnum_key;
/* the fnum is in setup[1] */
- p = pipe_state_find(private, trans->in.setup[1], req->session_info);
+ fnum_key = data_blob_const(&trans->in.setup[1], sizeof(trans->in.setup[1]));
+
+ p = pipe_state_find_key(private, req, &fnum_key);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -715,13 +700,16 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs,
/* SMBtrans - set named pipe state */
static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, struct smb_trans2 *trans)
+ struct ntvfs_request *req, struct smb_trans2 *trans)
{
struct ipc_private *private = ntvfs->private_data;
struct pipe_state *p;
+ DATA_BLOB fnum_key;
/* the fnum is in setup[1] */
- p = pipe_state_find(private, trans->in.setup[1], req->session_info);
+ fnum_key = data_blob_const(&trans->in.setup[1], sizeof(trans->in.setup[1]));
+
+ p = pipe_state_find_key(private, req, &fnum_key);
if (!p) {
return NT_STATUS_INVALID_HANDLE;
}