1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00
samba-mirror/source4/ntvfs/posix/pvfs_open.c

571 lines
14 KiB
C
Raw Normal View History

/*
Unix SMB/CIFS implementation.
POSIX NTVFS backend - open and close
Copyright (C) Andrew Tridgell 2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "include/includes.h"
#include "vfs_posix.h"
/*
find open file handle given fnum
*/
struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs,
struct smbsrv_request *req, uint16_t fnum)
{
struct pvfs_file *f;
f = idr_find(pvfs->idtree_fnum, fnum);
if (f == NULL) {
return NULL;
}
if (req->session != f->session) {
DEBUG(2,("pvfs_find_fd: attempt to use wrong session for fnum %d\n",
fnum));
return NULL;
}
return f;
}
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
/*
cleanup a open directory handle
*/
static int pvfs_dir_fd_destructor(void *p)
{
struct pvfs_file *f = p;
DLIST_REMOVE(f->pvfs->open_files, f);
idr_remove(f->pvfs->idtree_fnum, f->fnum);
return 0;
}
/*
open a directory
*/
static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
struct smbsrv_request *req,
struct pvfs_filename *name,
union smb_open *io)
{
struct pvfs_file *f;
int fnum;
NTSTATUS status;
uint32_t create_action;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
/* if the client says it must be a directory, and it isn't,
then fail */
if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
return NT_STATUS_NOT_A_DIRECTORY;
}
f = talloc_p(req, struct pvfs_file);
if (f == NULL) {
return NT_STATUS_NO_MEMORY;
}
fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX);
if (fnum == -1) {
talloc_free(f);
return NT_STATUS_TOO_MANY_OPENED_FILES;
}
f->fnum = fnum;
f->fd = -1;
f->name = talloc_steal(f, name);
f->session = req->session;
f->smbpid = req->smbpid;
f->pvfs = pvfs;
f->pending_list = NULL;
f->lock_count = 0;
f->locking_key = data_blob(NULL, 0);
/* setup a destructor to avoid leaks on abnormal termination */
talloc_set_destructor(f, pvfs_dir_fd_destructor);
switch (io->generic.in.open_disposition) {
case NTCREATEX_DISP_OPEN_IF:
break;
case NTCREATEX_DISP_OPEN:
if (!name->exists) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
break;
case NTCREATEX_DISP_CREATE:
if (name->exists) {
return NT_STATUS_OBJECT_NAME_COLLISION;
}
break;
case NTCREATEX_DISP_OVERWRITE_IF:
case NTCREATEX_DISP_OVERWRITE:
case NTCREATEX_DISP_SUPERSEDE:
default:
return NT_STATUS_INVALID_PARAMETER;
}
if (!name->exists) {
if (mkdir(name->full_name, 0755) == -1) {
return pvfs_map_errno(pvfs,errno);
}
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
PVFS_RESOLVE_NO_WILDCARD, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
create_action = NTCREATEX_ACTION_CREATED;
} else {
create_action = NTCREATEX_ACTION_EXISTED;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
}
if (!name->exists) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
DLIST_ADD(pvfs->open_files, f);
/* the open succeeded, keep this handle permanently */
talloc_steal(pvfs, f);
io->generic.out.oplock_level = NO_OPLOCK;
io->generic.out.fnum = f->fnum;
io->generic.out.create_action = create_action;
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
io->generic.out.write_time = name->dos.write_time;
io->generic.out.change_time = name->dos.change_time;
io->generic.out.attrib = name->dos.attrib;
io->generic.out.alloc_size = 0;
io->generic.out.size = 0;
io->generic.out.file_type = FILE_TYPE_DISK;
io->generic.out.ipc_state = 0;
io->generic.out.is_directory = 1;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
return NT_STATUS_OK;
}
/*
by using a destructor we make sure that abnormal cleanup will not
leak file descriptors (assuming at least the top level pointer is freed, which
will cascade down to here)
*/
static int pvfs_fd_destructor(void *p)
{
struct pvfs_file *f = p;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
DLIST_REMOVE(f->pvfs->open_files, f);
pvfs_lock_close(f->pvfs, f);
if (f->fd != -1) {
close(f->fd);
f->fd = -1;
}
idr_remove(f->pvfs->idtree_fnum, f->fnum);
return 0;
}
/*
form the lock context used for byte range locking and opendb
locking. Note that we must zero here to take account of
possible padding on some architectures
*/
static NTSTATUS pvfs_locking_key(struct pvfs_filename *name,
TALLOC_CTX *mem_ctx, DATA_BLOB *key)
{
struct {
dev_t device;
ino_t inode;
} lock_context;
ZERO_STRUCT(lock_context);
lock_context.device = name->st.st_dev;
lock_context.inode = name->st.st_ino;
*key = data_blob_talloc(mem_ctx, &lock_context, sizeof(lock_context));
if (key->data == NULL) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_OK;
}
/*
create a new file
*/
static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
struct smbsrv_request *req,
struct pvfs_filename *name,
union smb_open *io)
{
struct pvfs_file *f;
NTSTATUS status;
int flags, fnum, fd;
struct odb_lock *lck;
flags = O_RDWR;
f = talloc_p(req, struct pvfs_file);
if (f == NULL) {
return NT_STATUS_NO_MEMORY;
}
fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX);
if (fnum == -1) {
return NT_STATUS_TOO_MANY_OPENED_FILES;
}
/* create the file */
fd = open(name->full_name, flags | O_CREAT | O_EXCL, 0644);
if (fd == -1) {
idr_remove(pvfs->idtree_fnum, fnum);
return pvfs_map_errno(pvfs, errno);
}
/* re-resolve the open fd */
status = pvfs_resolve_name_fd(pvfs, fd, name);
if (!NT_STATUS_IS_OK(status)) {
idr_remove(pvfs->idtree_fnum, fnum);
return status;
}
/* form the lock context used for byte range locking and
opendb locking */
status = pvfs_locking_key(name, f, &f->locking_key);
if (!NT_STATUS_IS_OK(status)) {
idr_remove(pvfs->idtree_fnum, fnum);
return status;
}
/* grab a lock on the open file record */
lck = odb_lock(req, pvfs->odb_context, &f->locking_key);
if (lck == NULL) {
DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n",
name->full_name));
/* we were supposed to do a blocking lock, so something
is badly wrong! */
idr_remove(pvfs->idtree_fnum, fnum);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
f->fnum = fnum;
f->fd = fd;
f->name = talloc_steal(f, name);
f->session = req->session;
f->smbpid = req->smbpid;
f->pvfs = pvfs;
f->pending_list = NULL;
f->lock_count = 0;
DLIST_ADD(pvfs->open_files, f);
/* setup a destructor to avoid file descriptor leaks on
abnormal termination */
talloc_set_destructor(f, pvfs_fd_destructor);
io->generic.out.oplock_level = NO_OPLOCK;
io->generic.out.fnum = f->fnum;
io->generic.out.create_action = NTCREATEX_ACTION_CREATED;
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
io->generic.out.write_time = name->dos.write_time;
io->generic.out.change_time = name->dos.change_time;
io->generic.out.attrib = name->dos.attrib;
io->generic.out.alloc_size = name->dos.alloc_size;
io->generic.out.size = name->st.st_size;
io->generic.out.file_type = FILE_TYPE_DISK;
io->generic.out.ipc_state = 0;
io->generic.out.is_directory = 0;
/* success - keep the file handle */
talloc_steal(pvfs, f);
/* release the opendb lock (in case a chained request
blocks) */
talloc_free(lck);
return NT_STATUS_OK;
}
/*
open a file
*/
NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
struct smbsrv_request *req, union smb_open *io)
{
struct pvfs_state *pvfs = ntvfs->private_data;
int fd, flags;
struct pvfs_filename *name;
struct pvfs_file *f;
NTSTATUS status;
int fnum;
struct odb_lock *lck;
/* use the generic mapping code to avoid implementing all the
different open calls. This won't allow openx to work
perfectly as the mapping code has no way of knowing if two
opens are on the same connection, so this will need to
change eventually */
if (io->generic.level != RAW_OPEN_GENERIC) {
return ntvfs_map_open(req, io, ntvfs);
}
/* resolve the cifs name to a posix name */
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
PVFS_RESOLVE_NO_WILDCARD, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
/* directory opens are handled separately */
if ((name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) ||
(io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) {
return pvfs_open_directory(pvfs, req, name, io);
}
switch (io->generic.in.open_disposition) {
case NTCREATEX_DISP_SUPERSEDE:
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
if (!name->exists) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
flags = O_TRUNC;
break;
case NTCREATEX_DISP_OVERWRITE_IF:
flags = O_TRUNC;
break;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
case NTCREATEX_DISP_OPEN:
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
if (!name->exists) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
flags = 0;
break;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
case NTCREATEX_DISP_OVERWRITE:
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
if (!name->exists) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
flags = O_TRUNC;
break;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
case NTCREATEX_DISP_CREATE:
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
if (name->exists) {
return NT_STATUS_OBJECT_NAME_COLLISION;
}
flags = 0;
break;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
case NTCREATEX_DISP_OPEN_IF:
flags = 0;
break;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
default:
return NT_STATUS_INVALID_PARAMETER;
}
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
flags |= O_RDWR;
/* handle creating a new file separately */
if (!name->exists) {
status = pvfs_create_file(pvfs, req, name, io);
if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
return status;
}
/* we've hit a race - the file was created during this call */
if (io->generic.in.open_disposition == NTCREATEX_DISP_CREATE) {
return status;
}
/* try re-resolving the name */
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
PVFS_RESOLVE_NO_WILDCARD, &name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* fall through to a normal open */
}
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
f = talloc_p(req, struct pvfs_file);
if (f == NULL) {
return NT_STATUS_NO_MEMORY;
}
/* form the lock context used for byte range locking and
opendb locking */
status = pvfs_locking_key(name, f, &f->locking_key);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* get a lock on this file before the actual open */
lck = odb_lock(req, pvfs->odb_context, &f->locking_key);
if (lck == NULL) {
DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n",
name->full_name));
/* we were supposed to do a blocking lock, so something
is badly wrong! */
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
/* do the actual open */
fd = open(name->full_name, flags);
if (fd == -1) {
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
return pvfs_map_errno(pvfs, errno);
}
/* re-resolve the open fd */
status = pvfs_resolve_name_fd(pvfs, fd, name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* allocate a fnum */
fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX);
if (fnum == -1) {
return NT_STATUS_TOO_MANY_OPENED_FILES;
}
f->fnum = fnum;
f->fd = fd;
f->name = talloc_steal(f, name);
f->session = req->session;
f->smbpid = req->smbpid;
f->pvfs = pvfs;
f->pending_list = NULL;
f->lock_count = 0;
DLIST_ADD(pvfs->open_files, f);
/* setup a destructor to avoid file descriptor leaks on
abnormal termination */
talloc_set_destructor(f, pvfs_fd_destructor);
io->generic.out.oplock_level = NO_OPLOCK;
io->generic.out.fnum = f->fnum;
io->generic.out.create_action = NTCREATEX_ACTION_EXISTED;
io->generic.out.create_time = name->dos.create_time;
io->generic.out.access_time = name->dos.access_time;
io->generic.out.write_time = name->dos.write_time;
io->generic.out.change_time = name->dos.change_time;
io->generic.out.attrib = name->dos.attrib;
io->generic.out.alloc_size = name->dos.alloc_size;
io->generic.out.size = name->st.st_size;
io->generic.out.file_type = FILE_TYPE_DISK;
io->generic.out.ipc_state = 0;
io->generic.out.is_directory = 0;
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
/* success - keep the file handle */
talloc_steal(pvfs, f);
/* unlock the locking database */
talloc_free(lck);
return NT_STATUS_OK;
}
/*
close a file
*/
NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs,
struct smbsrv_request *req, union smb_close *io)
{
struct pvfs_state *pvfs = ntvfs->private_data;
struct pvfs_file *f;
NTSTATUS status;
if (io->generic.level != RAW_CLOSE_CLOSE) {
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
return ntvfs_map_close(req, io, ntvfs);
}
f = pvfs_find_fd(pvfs, req, io->close.in.fnum);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e)
2004-10-20 12:28:31 +04:00
if (f->fd != -1 &&
close(f->fd) == -1) {
status = pvfs_map_errno(pvfs, errno);
} else {
status = NT_STATUS_OK;
}
f->fd = -1;
/* the destructor takes care of the rest */
talloc_free(f);
return status;
}
/*
logoff - close all file descriptors open by a vuid
*/
NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs,
struct smbsrv_request *req)
{
struct pvfs_state *pvfs = ntvfs->private_data;
struct pvfs_file *f, *next;
for (f=pvfs->open_files;f;f=next) {
next = f->next;
if (f->session == req->session) {
DLIST_REMOVE(pvfs->open_files, f);
talloc_free(f);
}
}
return NT_STATUS_OK;
}
/*
exit - close files for the current pid
*/
NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs,
struct smbsrv_request *req)
{
struct pvfs_state *pvfs = ntvfs->private_data;
struct pvfs_file *f, *next;
for (f=pvfs->open_files;f;f=next) {
next = f->next;
if (f->smbpid == req->smbpid) {
DLIST_REMOVE(pvfs->open_files, f);
talloc_free(f);
}
}
return NT_STATUS_OK;
}