#include "include/includes.h"
#include "vfs_posix.h"
+/*
+ create file handles with convenient numbers for sniffers
+*/
+#define PVFS_MIN_FILE_FNUM 0x100
+#define PVFS_MIN_NEW_FNUM 0x200
+#define PVFS_MIN_DIR_FNUM 0x1000
/*
find open file handle given fnum
return NT_STATUS_NO_MEMORY;
}
- fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX);
+ fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_DIR_FNUM, UINT16_MAX);
if (fnum == -1) {
talloc_free(f);
return NT_STATUS_TOO_MANY_OPENED_FILES;
f->locking_key = data_blob(NULL, 0);
f->create_options = io->generic.in.create_options;
f->share_access = io->generic.in.share_access;
+ f->seek_offset = 0;
+ f->position = 0;
DLIST_ADD(pvfs->open_files, f);
talloc_set_destructor(f, pvfs_dir_fd_destructor);
if (!name->exists) {
- if (mkdir(name->full_name, 0755) == -1) {
+ uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY;
+ mode_t mode = pvfs_fileperms(pvfs, attrib);
+ if (mkdir(name->full_name, mode) == -1) {
return pvfs_map_errno(pvfs,errno);
}
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
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.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 = 1;
idr_remove(f->pvfs->idtree_fnum, f->fnum);
+ if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
+ if (unlink(f->name->full_name) != 0) {
+ DEBUG(0,("pvfs_close: failed to delete '%s'\n",
+ f->name->full_name));
+ }
+ }
+
lck = odb_lock(f, f->pvfs->odb_context, &f->locking_key);
if (lck == NULL) {
DEBUG(0,("Unable to lock opendb for close\n"));
f->name->full_name, nt_errstr(status)));
}
- if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
- if (unlink(f->name->full_name) != 0) {
- DEBUG(0,("pvfs_close: failed to delete '%s'\n",
- f->name->full_name));
- }
- }
+ talloc_free(lck);
return 0;
}
return NT_STATUS_CANNOT_DELETE;
}
- flags = O_RDWR;
+ if (access_mask & SEC_RIGHT_MAXIMUM_ALLOWED) {
+ access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE;
+ }
+
+ switch (access_mask & (SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA)) {
+ case SA_RIGHT_FILE_READ_DATA:
+ flags = O_RDONLY;
+ break;
+ case SA_RIGHT_FILE_WRITE_DATA:
+ flags = O_WRONLY;
+ break;
+ case SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_READ_DATA:
+ flags = O_RDWR;
+ break;
+ }
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);
+ fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_NEW_FNUM, UINT16_MAX);
if (fnum == -1) {
return NT_STATUS_TOO_MANY_OPENED_FILES;
}
- if (io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) {
- mode = 0444;
- } else {
- mode = 0644;
- }
+ mode = pvfs_fileperms(pvfs, io->ntcreatex.in.file_attr);
/* create the file */
fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode);
f->lock_count = 0;
f->create_options = io->generic.in.create_options;
f->share_access = io->generic.in.share_access;
- f->access_mask = io->generic.in.access_mask;
+ f->access_mask = access_mask;
+ f->seek_offset = 0;
+ f->position = 0;
DLIST_ADD(pvfs->open_files, f);
share_access = io->generic.in.share_access;
access_mask = io->generic.in.access_mask;
+ if (access_mask & SEC_RIGHT_MAXIMUM_ALLOWED) {
+ if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_READONLY)) {
+ access_mask = GENERIC_RIGHTS_FILE_READ;
+ } else {
+ access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE;
+ }
+ }
+
/* certain create options are not allowed */
if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
!(access_mask & STD_RIGHT_DELETE_ACCESS)) {
switch (io->generic.in.open_disposition) {
case NTCREATEX_DISP_SUPERSEDE:
- if (!name->exists) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
flags = O_TRUNC;
break;
return NT_STATUS_INVALID_PARAMETER;
}
- flags |= O_RDWR;
+ switch (access_mask & (SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA)) {
+ case SA_RIGHT_FILE_READ_DATA:
+ flags |= O_RDONLY;
+ break;
+ case SA_RIGHT_FILE_WRITE_DATA:
+ flags |= O_WRONLY;
+ break;
+ case SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_READ_DATA:
+ flags |= O_RDWR;
+ break;
+ }
/* handle creating a new file separately */
if (!name->exists) {
}
/* allocate a fnum */
- fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX);
+ fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_FILE_FNUM, UINT16_MAX);
if (fnum == -1) {
return NT_STATUS_TOO_MANY_OPENED_FILES;
}
f->lock_count = 0;
f->create_options = io->generic.in.create_options;
f->share_access = io->generic.in.share_access;
- f->access_mask = io->generic.in.access_mask;
+ f->access_mask = access_mask;
+ f->seek_offset = 0;
+ f->position = 0;
DLIST_ADD(pvfs->open_files, f);
struct pvfs_state *pvfs = ntvfs->private_data;
struct pvfs_file *f;
NTSTATUS status;
+ struct utimbuf unix_times;
if (io->generic.level != RAW_CLOSE_CLOSE) {
return ntvfs_map_close(req, io, ntvfs);
return NT_STATUS_INVALID_HANDLE;
}
+ if (!null_time(io->close.in.write_time)) {
+ unix_times.actime = 0;
+ unix_times.modtime = io->close.in.write_time;
+ utime(f->name->full_name, &unix_times);
+ }
+
if (f->fd != -1 &&
close(f->fd) == -1) {
status = pvfs_map_errno(pvfs, errno);
return status;
}
+
+
+/*
+ determine if a file can be deleted, or if it is prevented by an
+ already open file
+*/
+NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, struct pvfs_filename *name)
+{
+ NTSTATUS status;
+ DATA_BLOB key;
+
+ status = pvfs_locking_key(name, name, &key);
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = odb_can_open(pvfs->odb_context, &key,
+ NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE,
+ 0, STD_RIGHT_DELETE_ACCESS);
+
+ return status;
+}