diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-09-26 11:30:20 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:59:18 -0500 |
commit | e3880fa759cfa03222262327854fe7bbe585fe01 (patch) | |
tree | 7000172fad1b5cdcc0d071698ee3e203e61a8f4f /source4/ntvfs | |
parent | ad053090b817105a0974f4b8bf0b90e002297903 (diff) | |
download | samba-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.c | 25 | ||||
-rw-r--r-- | source4/ntvfs/ipc/vfs_ipc.c | 43 | ||||
-rw-r--r-- | source4/ntvfs/nbench/vfs_nbench.c | 14 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs.h | 3 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 53 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_qfileinfo.c | 2 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_read.c | 3 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_setfileinfo.c | 2 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_write.c | 4 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 10 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 8 | ||||
-rw-r--r-- | source4/ntvfs/simple/vfs_simple.c | 11 |
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' |