Fix include paths to new location of libutil.
[bbaumbach/samba-autobuild/.git] / source4 / ntvfs / simple / vfs_simple.c
index 35c18e3f1c52510403a2654827c07b99bf289797..5d904b4fcbdc0c6e6bc1ef20b4e213349e608b3d 100644 (file)
@@ -7,7 +7,7 @@
 
    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,
@@ -16,8 +16,7 @@
    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. 
@@ -31,7 +30,7 @@
 #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"
 
@@ -39,7 +38,7 @@
 #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
@@ -52,12 +51,13 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs,
 {
        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;
 
@@ -75,8 +75,6 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs,
 
        ntvfs->private_data = private;
 
-       DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename));
-
        return NT_STATUS_OK;
 }
 
@@ -91,15 +89,18 @@ static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs)
 /*
   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;
 }
 
 /*
@@ -282,12 +283,12 @@ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs,
                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);
        }
 
@@ -307,13 +308,15 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs,
        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;
@@ -379,7 +382,10 @@ do_open:
                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);
@@ -387,13 +393,16 @@ do_open:
 
        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);
@@ -483,13 +492,20 @@ static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs,
 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);
@@ -510,6 +526,8 @@ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs,
 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) {
@@ -518,7 +536,12 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs,
 
        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);
@@ -549,8 +572,28 @@ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs,
                           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;
 }
 
 /*
@@ -568,12 +611,12 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs,
                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);
        }
 
@@ -648,15 +691,21 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs,
                                 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);
                }
@@ -664,8 +713,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs,
        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;
                } 
@@ -676,7 +724,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs,
                }
 
                /* 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;
@@ -724,7 +772,7 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs,
        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;
@@ -778,7 +826,7 @@ static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs,
 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;
@@ -787,7 +835,11 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs,
        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;
        }
 
@@ -848,7 +900,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs,
 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;
@@ -857,7 +909,11 @@ static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs,
        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;
        }