summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-09-26 11:30:20 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:59:18 -0500
commite3880fa759cfa03222262327854fe7bbe585fe01 (patch)
tree7000172fad1b5cdcc0d071698ee3e203e61a8f4f /source4/ntvfs
parentad053090b817105a0974f4b8bf0b90e002297903 (diff)
downloadsamba-e3880fa759cfa03222262327854fe7bbe585fe01.tar.gz
samba-e3880fa759cfa03222262327854fe7bbe585fe01.tar.bz2
samba-e3880fa759cfa03222262327854fe7bbe585fe01.zip
r2660: - converted the libcli/raw/ library to use talloc_increase_ref_count()
rather than manual reference counts - properly support SMBexit in the cifs and posix backends - added a logoff method to all backends With these changes the RAW-CONTEXT test now passes against the posix backend (This used to be commit c315d6ac1cc40546fde1474702a6d66d07ee13c8)
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c25
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c43
-rw-r--r--source4/ntvfs/nbench/vfs_nbench.c14
-rw-r--r--source4/ntvfs/ntvfs.h3
-rw-r--r--source4/ntvfs/posix/pvfs_open.c53
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c2
-rw-r--r--source4/ntvfs/posix/pvfs_read.c3
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c2
-rw-r--r--source4/ntvfs/posix/pvfs_write.c4
-rw-r--r--source4/ntvfs/posix/vfs_posix.c10
-rw-r--r--source4/ntvfs/posix/vfs_posix.h8
-rw-r--r--source4/ntvfs/simple/vfs_simple.c11
12 files changed, 156 insertions, 22 deletions
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index 2ae41a674c..3931792ee8 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -162,7 +162,7 @@ static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon, int depth)
struct cvfs_private *private = tcon->ntvfs_private_list[depth];
smb_tree_disconnect(private->tree);
- smbcli_tree_close(private->tree);
+ talloc_free(private->tree);
return NT_STATUS_OK;
}
@@ -517,11 +517,29 @@ static NTSTATUS cvfs_close(struct smbsrv_request *req, union smb_close *io)
}
/*
- exit - closing files?
+ exit - closing files open by the pid
*/
static NTSTATUS cvfs_exit(struct smbsrv_request *req)
{
- return NT_STATUS_NOT_SUPPORTED;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
+ struct smbcli_request *c_req;
+
+ if (!req->async.send_fn) {
+ return smb_raw_exit(private->tree->session);
+ }
+
+ c_req = smb_raw_exit_send(private->tree->session);
+
+ SIMPLE_ASYNC_TAIL;
+}
+
+/*
+ logoff - closing files open by the user
+*/
+static NTSTATUS cvfs_logoff(struct smbsrv_request *req)
+{
+ /* we can't do this right in the cifs backend .... */
+ return NT_STATUS_OK;
}
/*
@@ -699,6 +717,7 @@ NTSTATUS ntvfs_cifs_init(void)
ops.search_next = cvfs_search_next;
ops.search_close = cvfs_search_close;
ops.trans = cvfs_trans;
+ ops.logoff = cvfs_logoff;
if (lp_parm_bool(-1, "cifs", "maptrans2", False)) {
ops.trans2 = cvfs_trans2;
diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c
index ce6629739a..33e1287d21 100644
--- a/source4/ntvfs/ipc/vfs_ipc.c
+++ b/source4/ntvfs/ipc/vfs_ipc.c
@@ -43,6 +43,13 @@ struct ipc_private {
uint16_t fnum;
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 smbsrv_session *session;
+
+ /* we need to remember the client pid that
+ opened the file so SMBexit works */
+ uint16_t smbpid;
} *pipe_list;
};
@@ -262,6 +269,9 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname,
DLIST_ADD(private->pipe_list, p);
+ p->smbpid = req->smbpid;
+ p->session = req->session;
+
*ps = p;
return NT_STATUS_OK;
@@ -514,11 +524,39 @@ static NTSTATUS ipc_close(struct smbsrv_request *req, union smb_close *io)
}
/*
- exit - closing files?
+ exit - closing files
*/
static NTSTATUS ipc_exit(struct smbsrv_request *req)
{
- return NT_STATUS_ACCESS_DENIED;
+ NTVFS_GET_PRIVATE(ipc_private, private, req);
+ struct pipe_state *p, *next;
+
+ for (p=private->pipe_list; p; p=next) {
+ next = p->next;
+ if (p->smbpid == req->smbpid) {
+ pipe_shutdown(private, p);
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ logoff - closing files open by the user
+*/
+static NTSTATUS ipc_logoff(struct smbsrv_request *req)
+{
+ NTVFS_GET_PRIVATE(ipc_private, private, req);
+ struct pipe_state *p, *next;
+
+ for (p=private->pipe_list; p; p=next) {
+ next = p->next;
+ if (p->session == req->session) {
+ pipe_shutdown(private, p);
+ }
+ }
+
+ return NT_STATUS_OK;
}
/*
@@ -733,6 +771,7 @@ NTSTATUS ntvfs_ipc_init(void)
ops.search_next = ipc_search_next;
ops.search_close = ipc_search_close;
ops.trans = ipc_trans;
+ ops.logoff = ipc_logoff;
/* register ourselves with the NTVFS subsystem. */
ret = register_backend("ntvfs", &ops);
diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c
index eebf6f1dde..90b5d43bd6 100644
--- a/source4/ntvfs/nbench/vfs_nbench.c
+++ b/source4/ntvfs/nbench/vfs_nbench.c
@@ -476,6 +476,19 @@ static NTSTATUS nbench_exit(struct smbsrv_request *req)
}
/*
+ logoff - closing files
+*/
+static NTSTATUS nbench_logoff(struct smbsrv_request *req)
+{
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
+ NTSTATUS status;
+
+ PASS_THRU_REQ(req, logoff, (req));
+
+ return status;
+}
+
+/*
lock a byte range
*/
static NTSTATUS nbench_lock(struct smbsrv_request *req, union smb_lock *lck)
@@ -672,6 +685,7 @@ NTSTATUS ntvfs_nbench_init(void)
ops.search_next = nbench_search_next;
ops.search_close = nbench_search_close;
ops.trans = nbench_trans;
+ ops.logoff = nbench_logoff;
/* we don't register a trans2 handler as we want to be able to
log individual trans2 requests */
diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h
index c9cf6de1e0..96434f44e2 100644
--- a/source4/ntvfs/ntvfs.h
+++ b/source4/ntvfs/ntvfs.h
@@ -74,6 +74,9 @@ struct ntvfs_ops {
/* trans interface - used by IPC backend for pipes and RAP calls */
NTSTATUS (*trans)(struct smbsrv_request *req, struct smb_trans2 *trans);
+
+ /* logoff - called when a vuid is closed */
+ NTSTATUS (*logoff)(struct smbsrv_request *req);
};
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index a1c6dcdcfe..f3bec4085e 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -27,11 +27,16 @@
/*
find open file handle given fnum
*/
-struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, uint16_t fnum)
+struct pvfs_file *pvfs_find_fd(struct smbsrv_request *req, uint16_t fnum)
{
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_file *f;
for (f=pvfs->open_files;f;f=f->next) {
if (f->fnum == fnum) {
+ if (req->session != f->session) {
+ DEBUG(2,("pvfs_find_fd: attempt to use wrong session for fnum %d\n", fnum));
+ return NULL;
+ }
return f;
}
}
@@ -146,6 +151,8 @@ do_open:
f->fnum = fd;
f->fd = fd;
f->name = talloc_steal(f, name);
+ f->session = req->session;
+ f->smbpid = req->smbpid;
/* setup a destructor to avoid file descriptor leaks on
abnormal termination */
@@ -183,7 +190,7 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io)
return NT_STATUS_INVALID_LEVEL;
}
- f = pvfs_find_fd(pvfs, io->close.in.fnum);
+ f = pvfs_find_fd(req, io->close.in.fnum);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -202,3 +209,45 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io)
return status;
}
+
+/*
+ logoff - close all file descriptors open by a vuid
+*/
+NTSTATUS pvfs_logoff(struct smbsrv_request *req)
+{
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
+ struct pvfs_file *f, *next;
+
+ for (f=pvfs->open_files;f;f=next) {
+ next = f->next;
+ if (f->session == req->session) {
+ talloc_set_destructor(f, NULL);
+ DLIST_REMOVE(pvfs->open_files, f);
+ talloc_free(f);
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ exit - close files for the current pid
+*/
+NTSTATUS pvfs_exit(struct smbsrv_request *req)
+{
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
+ struct pvfs_file *f, *next;
+
+ for (f=pvfs->open_files;f;f=next) {
+ next = f->next;
+ if (f->smbpid == req->smbpid) {
+ talloc_set_destructor(f, NULL);
+ DLIST_REMOVE(pvfs->open_files, f);
+ talloc_free(f);
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index 649036b09a..81706bcfe8 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -114,7 +114,7 @@ NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info)
return ntvfs_map_qfileinfo(req, info, pvfs->ops);
}
- f = pvfs_find_fd(pvfs, info->generic.in.fnum);
+ f = pvfs_find_fd(req, info->generic.in.fnum);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c
index cbb0317638..72ac00a32d 100644
--- a/source4/ntvfs/posix/pvfs_read.c
+++ b/source4/ntvfs/posix/pvfs_read.c
@@ -36,7 +36,8 @@ NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd)
return NT_STATUS_NOT_SUPPORTED;
}
- f = pvfs_find_fd(pvfs, rd->readx.in.fnum);
+
+ f = pvfs_find_fd(req, rd->readx.in.fnum);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index c2c58415be..2ea2fdaf8e 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -33,7 +33,7 @@ NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req,
struct utimbuf unix_times;
struct pvfs_file *f;
- f = pvfs_find_fd(pvfs, info->generic.file.fnum);
+ f = pvfs_find_fd(req, info->generic.file.fnum);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c
index ac9d23b88f..02ba1b8228 100644
--- a/source4/ntvfs/posix/pvfs_write.c
+++ b/source4/ntvfs/posix/pvfs_write.c
@@ -35,7 +35,7 @@ NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr)
switch (wr->generic.level) {
case RAW_WRITE_WRITEX:
- f = pvfs_find_fd(pvfs, wr->writex.in.fnum);
+ f = pvfs_find_fd(req, wr->writex.in.fnum);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -53,7 +53,7 @@ NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr)
return NT_STATUS_OK;
case RAW_WRITE_WRITE:
- f = pvfs_find_fd(pvfs, wr->write.in.fnum);
+ f = pvfs_find_fd(req, wr->write.in.fnum);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c
index 8705317b2a..7ae7c6759a 100644
--- a/source4/ntvfs/posix/vfs_posix.c
+++ b/source4/ntvfs/posix/vfs_posix.c
@@ -161,15 +161,6 @@ static NTSTATUS pvfs_flush(struct smbsrv_request *req, struct smb_flush *io)
}
/*
- exit - closing files?
-*/
-static NTSTATUS pvfs_exit(struct smbsrv_request *req)
-{
- DEBUG(0,("pvfs_exit not implemented\n"));
- return NT_STATUS_NOT_SUPPORTED;
-}
-
-/*
lock a byte range
*/
static NTSTATUS pvfs_lock(struct smbsrv_request *req, union smb_lock *lck)
@@ -241,6 +232,7 @@ NTSTATUS ntvfs_posix_init(void)
ops.search_next = pvfs_search_next;
ops.search_close = pvfs_search_close;
ops.trans = pvfs_trans;
+ ops.logoff = pvfs_logoff;
/* register ourselves with the NTVFS subsystem. We register
under the name 'default' as we wish to be the default
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index bfb1fbf7ca..96ab7f85b2 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -107,6 +107,14 @@ struct pvfs_file {
int fd;
uint16_t fnum;
struct pvfs_filename *name;
+
+ /* we need to remember the session it was opened on,
+ as it is illegal to operate on someone elses fnum */
+ struct smbsrv_session *session;
+
+ /* we need to remember the client pid that
+ opened the file so SMBexit works */
+ uint16_t smbpid;
};
diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c
index 5b2fe9df56..f60646ed77 100644
--- a/source4/ntvfs/simple/vfs_simple.c
+++ b/source4/ntvfs/simple/vfs_simple.c
@@ -589,7 +589,7 @@ static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io)
}
/*
- exit - closing files?
+ exit - closing files
*/
static NTSTATUS svfs_exit(struct smbsrv_request *req)
{
@@ -597,6 +597,14 @@ static NTSTATUS svfs_exit(struct smbsrv_request *req)
}
/*
+ logoff - closing files
+*/
+static NTSTATUS svfs_logoff(struct smbsrv_request *req)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+/*
lock a byte range
*/
static NTSTATUS svfs_lock(struct smbsrv_request *req, union smb_lock *lck)
@@ -962,6 +970,7 @@ NTSTATUS ntvfs_simple_init(void)
ops.search_next = svfs_search_next;
ops.search_close = svfs_search_close;
ops.trans = svfs_trans;
+ ops.logoff = svfs_logoff;
/* register ourselves with the NTVFS subsystem. We register
under names 'simple'