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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
this implements a very simple NTVFS filesystem backend.
#include "system/filesys.h"
#include "svfs.h"
#include "system/time.h"
-#include "dlinklist.h"
+#include "../lib/util/dlinklist.h"
#include "ntvfs/ntvfs.h"
#include "ntvfs/simple/proto.h"
#define O_DIRECTORY 0
#endif
-#define CHECK_READ_ONLY(req) do { if (lp_readonly(ntvfs->ctx->config.snum)) return NT_STATUS_ACCESS_DENIED; } while (0)
+#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, true)) return NT_STATUS_ACCESS_DENIED; } while (0)
/*
connect to a share - used when a tree_connect operation comes
{
struct stat st;
struct svfs_private *private;
- int snum = ntvfs->ctx->config.snum;
+ struct share_config *scfg = ntvfs->ctx->config;
private = talloc(ntvfs, struct svfs_private);
-
+ NT_STATUS_HAVE_NO_MEMORY(private);
+ private->ntvfs = ntvfs;
private->next_search_handle = 0;
- private->connectpath = talloc_strdup(private, lp_pathname(snum));
+ private->connectpath = talloc_strdup(private, share_string_option(scfg, SHARE_PATH, ""));
private->open_files = NULL;
private->search = NULL;
ntvfs->private_data = private;
- DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename));
-
return NT_STATUS_OK;
}
/*
find open file handle given fd
*/
-static struct svfs_file *find_fd(struct svfs_private *private, int fd)
+static struct svfs_file *find_fd(struct svfs_private *private, struct ntvfs_handle *handle)
{
struct svfs_file *f;
- for (f=private->open_files;f;f=f->next) {
- if (f->fd == fd) {
- return f;
- }
- }
- return NULL;
+ void *p;
+
+ p = ntvfs_handle_get_backend_data(handle, private->ntvfs);
+ if (!p) return NULL;
+
+ f = talloc_get_type(p, struct svfs_file);
+ if (!f) return NULL;
+
+ return f;
}
/*
return ntvfs_map_qfileinfo(ntvfs, req, info);
}
- f = find_fd(private, info->generic.in.file.fnum);
+ f = find_fd(private, info->generic.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
- if (fstat(info->generic.in.file.fnum, &st) == -1) {
+ if (fstat(f->fd, &st) == -1) {
return map_nt_error_from_unix(errno);
}
int fd, flags;
struct svfs_file *f;
int create_flags, rdwr_flags;
- BOOL readonly;
+ bool readonly;
+ NTSTATUS status;
+ struct ntvfs_handle *handle;
if (io->generic.level != RAW_OPEN_GENERIC) {
return ntvfs_map_open(ntvfs, req, io);
}
- readonly = lp_readonly(ntvfs->ctx->config.snum);
+ readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, SHARE_READONLY_DEFAULT);
if (readonly) {
create_flags = 0;
rdwr_flags = O_RDONLY;
return map_nt_error_from_unix(errno);
}
- f = talloc(ntvfs, struct svfs_file);
+ status = ntvfs_handle_new(ntvfs, req, &handle);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ f = talloc(handle, struct svfs_file);
NT_STATUS_HAVE_NO_MEMORY(f);
f->fd = fd;
f->name = talloc_strdup(f, unix_path);
DLIST_ADD(private->open_files, f);
+ status = ntvfs_handle_set_backend_data(handle, ntvfs, f);
+ NT_STATUS_NOT_OK_RETURN(status);
+
ZERO_STRUCT(io->generic.out);
unix_to_nt_time(&io->generic.out.create_time, st.st_ctime);
unix_to_nt_time(&io->generic.out.access_time, st.st_atime);
unix_to_nt_time(&io->generic.out.write_time, st.st_mtime);
unix_to_nt_time(&io->generic.out.change_time, st.st_mtime);
- io->generic.out.file.fnum = fd;
+ io->generic.out.file.ntvfs = handle;
io->generic.out.alloc_size = st.st_size;
io->generic.out.size = st.st_size;
io->generic.out.attrib = svfs_unix_to_dos_attrib(st.st_mode);
static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req, union smb_read *rd)
{
+ struct svfs_private *private = ntvfs->private_data;
+ struct svfs_file *f;
ssize_t ret;
if (rd->generic.level != RAW_READ_READX) {
return NT_STATUS_NOT_SUPPORTED;
}
- ret = pread(rd->readx.in.file.fnum,
+ f = find_fd(private, rd->readx.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ ret = pread(f->fd,
rd->readx.out.data,
rd->readx.in.maxcnt,
rd->readx.in.offset);
static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req, union smb_write *wr)
{
+ struct svfs_private *private = ntvfs->private_data;
+ struct svfs_file *f;
ssize_t ret;
if (wr->generic.level != RAW_WRITE_WRITEX) {
CHECK_READ_ONLY(req);
- ret = pwrite(wr->writex.in.file.fnum,
+ f = find_fd(private, wr->writex.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ ret = pwrite(f->fd,
wr->writex.in.data,
wr->writex.in.count,
wr->writex.in.offset);
struct ntvfs_request *req,
union smb_flush *io)
{
- fsync(io->flush.in.file.fnum);
- return NT_STATUS_OK;
+ struct svfs_private *private = ntvfs->private_data;
+ struct svfs_file *f;
+
+ switch (io->generic.level) {
+ case RAW_FLUSH_FLUSH:
+ case RAW_FLUSH_SMB2:
+ /* ignore the additional unknown option in SMB2 */
+ f = find_fd(private, io->generic.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ fsync(f->fd);
+ return NT_STATUS_OK;
+
+ case RAW_FLUSH_ALL:
+ for (f=private->open_files;f;f=f->next) {
+ fsync(f->fd);
+ }
+ return NT_STATUS_OK;
+ }
+
+ return NT_STATUS_INVALID_LEVEL;
}
/*
return NT_STATUS_INVALID_LEVEL;
}
- f = find_fd(private, io->close.in.file.fnum);
+ f = find_fd(private, io->close.in.file.ntvfs);
if (!f) {
return NT_STATUS_INVALID_HANDLE;
}
- if (close(io->close.in.file.fnum) == -1) {
+ if (close(f->fd) == -1) {
return map_nt_error_from_unix(errno);
}
struct ntvfs_request *req,
union smb_setfileinfo *info)
{
+ struct svfs_private *private = ntvfs->private_data;
+ struct svfs_file *f;
struct utimbuf unix_times;
- int fd;
CHECK_READ_ONLY(req);
-
+
+ f = find_fd(private, info->generic.in.file.ntvfs);
+ if (!f) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
switch (info->generic.level) {
case RAW_SFILEINFO_END_OF_FILE_INFO:
case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
- if (ftruncate(info->end_of_file_info.in.file.fnum,
+ if (ftruncate(f->fd,
info->end_of_file_info.in.size) == -1) {
return map_nt_error_from_unix(errno);
}
case RAW_SFILEINFO_SETATTRE:
unix_times.actime = info->setattre.in.access_time;
unix_times.modtime = info->setattre.in.write_time;
- fd = info->setattre.in.file.fnum;
-
+
if (unix_times.actime == 0 && unix_times.modtime == 0) {
break;
}
}
/* Set the date on this file */
- if (svfs_file_utime(fd, &unix_times) != 0) {
+ if (svfs_file_utime(f->fd, &unix_times) != 0) {
return NT_STATUS_ACCESS_DENIED;
}
break;
fs->generic.out.quota_soft = 0;
fs->generic.out.quota_hard = 0;
fs->generic.out.quota_flags = 0;
- fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(ntvfs->ctx->config.snum));
+ fs->generic.out.volume_name = talloc_strdup(req, ntvfs->ctx->config->name);
fs->generic.out.fs_type = ntvfs->ctx->fs_type;
return NT_STATUS_OK;
static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req, union smb_search_first *io,
void *search_private,
- BOOL (*callback)(void *, union smb_search_data *))
+ bool (*callback)(void *, const union smb_search_data *))
{
struct svfs_dir *dir;
int i;
union smb_search_data file;
uint_t max_count;
- if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) {
+ if (io->generic.level != RAW_SEARCH_TRANS2) {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) {
return NT_STATUS_NOT_SUPPORTED;
}
static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs,
struct ntvfs_request *req, union smb_search_next *io,
void *search_private,
- BOOL (*callback)(void *, union smb_search_data *))
+ bool (*callback)(void *, const union smb_search_data *))
{
struct svfs_dir *dir;
int i;
union smb_search_data file;
uint_t max_count;
- if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) {
+ if (io->generic.level != RAW_SEARCH_TRANS2) {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) {
return NT_STATUS_NOT_SUPPORTED;
}