tdb_wrap: Remove tdb_wrap_open_ again
[kai/samba-autobuild/.git] / source4 / ntvfs / posix / vfs_posix.c
index dd8c3fe81f2acddfd4a71715c4f4adb721dde4d4..304a9ff8fe58063c12c69c93079fac417dd28fb9 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
 
    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,
    (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
    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 most of the POSIX NTVFS backend
 */
 /*
   this implements most of the POSIX NTVFS backend
 #include "includes.h"
 #include "vfs_posix.h"
 #include "librpc/gen_ndr/security.h"
 #include "includes.h"
 #include "vfs_posix.h"
 #include "librpc/gen_ndr/security.h"
-#include "lib/tdb/include/tdb.h"
-#include "db_wrap.h"
+#include "tdb_compat.h"
+#include "lib/tdb_wrap/tdb_wrap.h"
 #include "libcli/security/security.h"
 #include "lib/events/events.h"
 #include "libcli/security/security.h"
 #include "lib/events/events.h"
-
+#include "param/param.h"
 
 /*
   setup config options for a posix share
 */
 static void pvfs_setup_options(struct pvfs_state *pvfs)
 {
 
 /*
   setup config options for a posix share
 */
 static void pvfs_setup_options(struct pvfs_state *pvfs)
 {
-       int snum = pvfs->ntvfs->ctx->config.snum;
-       const char *eadb;
-
-       if (lp_map_hidden(snum))     pvfs->flags |= PVFS_FLAG_MAP_HIDDEN;
-       if (lp_map_archive(snum))    pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE;
-       if (lp_map_system(snum))     pvfs->flags |= PVFS_FLAG_MAP_SYSTEM;
-       if (lp_readonly(snum))       pvfs->flags |= PVFS_FLAG_READONLY;
-       if (lp_strict_sync(snum))    pvfs->flags |= PVFS_FLAG_STRICT_SYNC;
-       if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING;
-       if (lp_ci_filesystem(snum))  pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM;
-
-       if (lp_parm_bool(snum, "posix", "fakeoplocks", False)) {
+       struct share_config *scfg = pvfs->ntvfs->ctx->config;
+       char *eadb;
+       char *xattr_backend;
+       bool def_perm_override = false;
+
+       if (share_bool_option(scfg, SHARE_MAP_HIDDEN, SHARE_MAP_HIDDEN_DEFAULT))
+               pvfs->flags |= PVFS_FLAG_MAP_HIDDEN;
+       if (share_bool_option(scfg, SHARE_MAP_ARCHIVE, SHARE_MAP_ARCHIVE_DEFAULT))
+               pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE;
+       if (share_bool_option(scfg, SHARE_MAP_SYSTEM, SHARE_MAP_SYSTEM_DEFAULT))
+               pvfs->flags |= PVFS_FLAG_MAP_SYSTEM;
+       if (share_bool_option(scfg, SHARE_READONLY, SHARE_READONLY_DEFAULT))
+               pvfs->flags |= PVFS_FLAG_READONLY;
+       if (share_bool_option(scfg, SHARE_STRICT_SYNC, SHARE_STRICT_SYNC_DEFAULT))
+               pvfs->flags |= PVFS_FLAG_STRICT_SYNC;
+       if (share_bool_option(scfg, SHARE_STRICT_LOCKING, SHARE_STRICT_LOCKING_DEFAULT))
+               pvfs->flags |= PVFS_FLAG_STRICT_LOCKING;
+       if (share_bool_option(scfg, SHARE_CI_FILESYSTEM, SHARE_CI_FILESYSTEM_DEFAULT))
+               pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM;
+       if (share_bool_option(scfg, PVFS_FAKE_OPLOCKS, PVFS_FAKE_OPLOCKS_DEFAULT))
                pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS;
                pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS;
-       }
+       if (share_bool_option(scfg, PVFS_AIO, false))
+               pvfs->flags |= PVFS_FLAG_LINUX_AIO;
 
 
+#if defined(O_DIRECTORY) && defined(O_NOFOLLOW)
+       /* set PVFS_PERM_OVERRIDE by default only if the system
+        * supports the necessary capabilities to make it secure
+        */
+       def_perm_override = true;
+#endif
+       if (share_bool_option(scfg, PVFS_PERM_OVERRIDE, def_perm_override))
+               pvfs->flags |= PVFS_FLAG_PERM_OVERRIDE;
+
+       /* file perm options */
+       pvfs->options.create_mask       = share_int_option(scfg,
+                                                          SHARE_CREATE_MASK,
+                                                          SHARE_CREATE_MASK_DEFAULT);
+       pvfs->options.dir_mask          = share_int_option(scfg,
+                                                          SHARE_DIR_MASK,
+                                                          SHARE_DIR_MASK_DEFAULT);
+       pvfs->options.force_dir_mode    = share_int_option(scfg,
+                                                          SHARE_FORCE_DIR_MODE,
+                                                          SHARE_FORCE_DIR_MODE_DEFAULT);
+       pvfs->options.force_create_mode = share_int_option(scfg,
+                                                          SHARE_FORCE_CREATE_MODE,
+                                                          SHARE_FORCE_CREATE_MODE_DEFAULT);
        /* this must be a power of 2 */
        /* this must be a power of 2 */
-       pvfs->alloc_size_rounding = lp_parm_int(snum, 
-                                               "posix", "allocationrounding", 512);
+       pvfs->alloc_size_rounding = share_int_option(scfg,
+                                                       PVFS_ALLOCATION_ROUNDING,
+                                                       PVFS_ALLOCATION_ROUNDING_DEFAULT);
 
 
-       pvfs->search.inactivity_time = lp_parm_int(snum, 
-                                                  "posix", "searchinactivity", 300);
+       pvfs->search.inactivity_time = share_int_option(scfg,
+                                                       PVFS_SEARCH_INACTIVITY,
+                                                       PVFS_SEARCH_INACTIVITY_DEFAULT);
 
 #if HAVE_XATTR_SUPPORT
 
 #if HAVE_XATTR_SUPPORT
-       if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE;
+       if (share_bool_option(scfg, PVFS_XATTR, PVFS_XATTR_DEFAULT))
+               pvfs->flags |= PVFS_FLAG_XATTR_ENABLE;
 #endif
 
 #endif
 
-       pvfs->sharing_violation_delay = lp_parm_int(snum, "posix", "sharedelay", 1000000);
+       pvfs->sharing_violation_delay = share_int_option(scfg,
+                                                       PVFS_SHARE_DELAY,
+                                                       PVFS_SHARE_DELAY_DEFAULT);
 
 
-       pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum));
+       pvfs->oplock_break_timeout = share_int_option(scfg,
+                                                     PVFS_OPLOCK_TIMEOUT,
+                                                     PVFS_OPLOCK_TIMEOUT_DEFAULT);
+
+       pvfs->writetime_delay = share_int_option(scfg,
+                                                PVFS_WRITETIME_DELAY,
+                                                PVFS_WRITETIME_DELAY_DEFAULT);
+
+       pvfs->share_name = talloc_strdup(pvfs, scfg->name);
 
        pvfs->fs_attribs = 
                FS_ATTR_CASE_SENSITIVE_SEARCH | 
 
        pvfs->fs_attribs = 
                FS_ATTR_CASE_SENSITIVE_SEARCH | 
@@ -75,10 +118,13 @@ static void pvfs_setup_options(struct pvfs_state *pvfs)
                FS_ATTR_SPARSE_FILES;
 
        /* allow xattrs to be stored in a external tdb */
                FS_ATTR_SPARSE_FILES;
 
        /* allow xattrs to be stored in a external tdb */
-       eadb = lp_parm_string(snum, "posix", "eadb");
+       eadb = share_string_option(pvfs, scfg, PVFS_EADB, NULL);
        if (eadb != NULL) {
        if (eadb != NULL) {
-               pvfs->ea_db = tdb_wrap_open(pvfs, eadb, 50000,  
-                                           TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+               pvfs->ea_db = tdb_wrap_open(
+                       pvfs, eadb, 50000,
+                       lpcfg_tdb_flags(pvfs->ntvfs->ctx->lp_ctx, TDB_DEFAULT),
+                       O_RDWR|O_CREAT, 0600);
+               TALLOC_FREE(eadb);
                if (pvfs->ea_db != NULL) {
                        pvfs->flags |= PVFS_FLAG_XATTR_ENABLE;
                } else {
                if (pvfs->ea_db != NULL) {
                        pvfs->flags |= PVFS_FLAG_XATTR_ENABLE;
                } else {
@@ -102,11 +148,15 @@ static void pvfs_setup_options(struct pvfs_state *pvfs)
        if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) {
                pvfs_xattr_probe(pvfs);
        }
        if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) {
                pvfs_xattr_probe(pvfs);
        }
+
+       /* enable an ACL backend */
+       xattr_backend = share_string_option(pvfs, scfg, PVFS_ACL, "xattr");
+       pvfs->acl_ops = pvfs_acl_backend_byname(xattr_backend);
+       TALLOC_FREE(xattr_backend);
 }
 
 }
 
-static int pvfs_state_destructor(void *ptr)
+static int pvfs_state_destructor(struct pvfs_state *pvfs)
 {
 {
-       struct pvfs_state *pvfs = talloc_get_type(ptr, struct pvfs_state);
        struct pvfs_file *f, *fn;
        struct pvfs_search_state *s, *sn;
 
        struct pvfs_file *f, *fn;
        struct pvfs_search_state *s, *sn;
 
@@ -134,18 +184,48 @@ static int pvfs_state_destructor(void *ptr)
   that comes later)
 */
 static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
   that comes later)
 */
 static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
-                            struct ntvfs_request *req, const char *sharename)
+                            struct ntvfs_request *req,
+                            union smb_tcon* tcon)
 {
        struct pvfs_state *pvfs;
        struct stat st;
        char *base_directory;
        NTSTATUS status;
 {
        struct pvfs_state *pvfs;
        struct stat st;
        char *base_directory;
        NTSTATUS status;
+       const char *sharename;
+
+       switch (tcon->generic.level) {
+       case RAW_TCON_TCON:
+               sharename = tcon->tcon.in.service;
+               break;
+       case RAW_TCON_TCONX:
+               sharename = tcon->tconx.in.path;
+               break;
+       case RAW_TCON_SMB2:
+               sharename = tcon->smb2.in.path;
+               break;
+       default:
+               return NT_STATUS_INVALID_LEVEL;
+       }
+
+       if (strncmp(sharename, "\\\\", 2) == 0) {
+               char *p = strchr(sharename+2, '\\');
+               if (p) {
+                       sharename = p + 1;
+               }
+       }
+
+       /*
+        * TODO: call this from ntvfs_posix_init()
+        *       but currently we don't have a lp_ctx there
+        */
+       status = pvfs_acl_init();
+       NT_STATUS_NOT_OK_RETURN(status);
 
        pvfs = talloc_zero(ntvfs, struct pvfs_state);
        NT_STATUS_HAVE_NO_MEMORY(pvfs);
 
        /* for simplicity of path construction, remove any trailing slash now */
 
        pvfs = talloc_zero(ntvfs, struct pvfs_state);
        NT_STATUS_HAVE_NO_MEMORY(pvfs);
 
        /* for simplicity of path construction, remove any trailing slash now */
-       base_directory = talloc_strdup(pvfs, lp_pathname(ntvfs->ctx->config.snum));
+       base_directory = share_string_option(pvfs, ntvfs->ctx->config, SHARE_PATH, "");
        NT_STATUS_HAVE_NO_MEMORY(base_directory);
        if (strcmp(base_directory, "/") != 0) {
                trim_string(base_directory, NULL, "/");
        NT_STATUS_HAVE_NO_MEMORY(base_directory);
        if (strcmp(base_directory, "/") != 0) {
                trim_string(base_directory, NULL, "/");
@@ -168,19 +248,22 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
        ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:");
        NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type);
 
        ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:");
        NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type);
 
+       if (tcon->generic.level == RAW_TCON_TCONX) {
+               tcon->tconx.out.fs_type = ntvfs->ctx->fs_type;
+               tcon->tconx.out.dev_type = ntvfs->ctx->dev_type;
+       }
+
        ntvfs->private_data = pvfs;
 
        ntvfs->private_data = pvfs;
 
-       pvfs->brl_context = brl_init(pvfs, 
-                                    pvfs->ntvfs->ctx->server_id,  
-                                    pvfs->ntvfs->ctx->config.snum,
+       pvfs->brl_context = brlock_init(pvfs, 
+                                    pvfs->ntvfs->ctx->server_id,
+                                    pvfs->ntvfs->ctx->lp_ctx,
                                     pvfs->ntvfs->ctx->msg_ctx);
        if (pvfs->brl_context == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
                                     pvfs->ntvfs->ctx->msg_ctx);
        if (pvfs->brl_context == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       pvfs->odb_context = odb_init(pvfs, 
-                                    pvfs->ntvfs->ctx->server_id,  
-                                    pvfs->ntvfs->ctx->msg_ctx);
+       pvfs->odb_context = odb_init(pvfs, pvfs->ntvfs->ctx);
        if (pvfs->odb_context == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
        if (pvfs->odb_context == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -189,17 +272,9 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
        pvfs->notify_context = notify_init(pvfs, 
                                           pvfs->ntvfs->ctx->server_id,  
                                           pvfs->ntvfs->ctx->msg_ctx, 
        pvfs->notify_context = notify_init(pvfs, 
                                           pvfs->ntvfs->ctx->server_id,  
                                           pvfs->ntvfs->ctx->msg_ctx, 
-                                          event_context_find(pvfs),
-                                          pvfs->ntvfs->ctx->config.snum);
-
-       pvfs->sidmap = sidmap_open(pvfs);
-       if (pvfs->sidmap == NULL) {
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-
-       /* allocate the fnum id -> ptr tree */
-       pvfs->files.idtree = idr_init(pvfs);
-       NT_STATUS_HAVE_NO_MEMORY(pvfs->files.idtree);
+                                          pvfs->ntvfs->ctx->lp_ctx,
+                                          pvfs->ntvfs->ctx->event_ctx,
+                                          pvfs->ntvfs->ctx->config);
 
        /* allocate the search handle -> ptr tree */
        pvfs->search.idtree = idr_init(pvfs);
 
        /* allocate the search handle -> ptr tree */
        pvfs->search.idtree = idr_init(pvfs);
@@ -215,7 +290,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
 #ifdef SIGXFSZ
        /* who had the stupid idea to generate a signal on a large
           file write instead of just failing it!? */
 #ifdef SIGXFSZ
        /* who had the stupid idea to generate a signal on a large
           file write instead of just failing it!? */
-       BlockSignals(True, SIGXFSZ);
+       BlockSignals(true, SIGXFSZ);
 #endif
 
        return NT_STATUS_OK;
 #endif
 
        return NT_STATUS_OK;
@@ -236,7 +311,8 @@ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs,
                             struct ntvfs_request *req,
                             union smb_chkpath *cp)
 {
                             struct ntvfs_request *req,
                             union smb_chkpath *cp)
 {
-       struct pvfs_state *pvfs = ntvfs->private_data;
+       struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data,
+                                 struct pvfs_state);
        struct pvfs_filename *name;
        NTSTATUS status;
 
        struct pvfs_filename *name;
        NTSTATUS status;
 
@@ -288,55 +364,64 @@ NTSTATUS ntvfs_posix_init(void)
 {
        NTSTATUS ret;
        struct ntvfs_ops ops;
 {
        NTSTATUS ret;
        struct ntvfs_ops ops;
+       NTVFS_CURRENT_CRITICAL_SIZES(vers);
 
        ZERO_STRUCT(ops);
 
        ops.type = NTVFS_DISK;
        
        /* fill in all the operations */
 
        ZERO_STRUCT(ops);
 
        ops.type = NTVFS_DISK;
        
        /* fill in all the operations */
-       ops.connect = pvfs_connect;
-       ops.disconnect = pvfs_disconnect;
-       ops.unlink = pvfs_unlink;
-       ops.chkpath = pvfs_chkpath;
-       ops.qpathinfo = pvfs_qpathinfo;
-       ops.setpathinfo = pvfs_setpathinfo;
-       ops.open = pvfs_open;
-       ops.mkdir = pvfs_mkdir;
-       ops.rmdir = pvfs_rmdir;
-       ops.rename = pvfs_rename;
-       ops.copy = pvfs_copy;
-       ops.ioctl = pvfs_ioctl;
-       ops.read = pvfs_read;
-       ops.write = pvfs_write;
-       ops.seek = pvfs_seek;
-       ops.flush = pvfs_flush; 
-       ops.close = pvfs_close;
-       ops.exit = pvfs_exit;
-       ops.lock = pvfs_lock;
-       ops.setfileinfo = pvfs_setfileinfo;
-       ops.qfileinfo = pvfs_qfileinfo;
-       ops.fsinfo = pvfs_fsinfo;
-       ops.lpq = pvfs_lpq;
-       ops.search_first = pvfs_search_first;
-       ops.search_next = pvfs_search_next;
-       ops.search_close = pvfs_search_close;
-       ops.trans = pvfs_trans;
-       ops.logoff = pvfs_logoff;
-       ops.async_setup = pvfs_async_setup;
-       ops.cancel = pvfs_cancel;
-       ops.notify = pvfs_notify;
+       ops.connect_fn = pvfs_connect;
+       ops.disconnect_fn = pvfs_disconnect;
+       ops.unlink_fn = pvfs_unlink;
+       ops.chkpath_fn = pvfs_chkpath;
+       ops.qpathinfo_fn = pvfs_qpathinfo;
+       ops.setpathinfo_fn = pvfs_setpathinfo;
+       ops.open_fn = pvfs_open;
+       ops.mkdir_fn = pvfs_mkdir;
+       ops.rmdir_fn = pvfs_rmdir;
+       ops.rename_fn = pvfs_rename;
+       ops.copy_fn = pvfs_copy;
+       ops.ioctl_fn = pvfs_ioctl;
+       ops.read_fn = pvfs_read;
+       ops.write_fn = pvfs_write;
+       ops.seek_fn = pvfs_seek;
+       ops.flush_fn = pvfs_flush;
+       ops.close_fn = pvfs_close;
+       ops.exit_fn = pvfs_exit;
+       ops.lock_fn = pvfs_lock;
+       ops.setfileinfo_fn = pvfs_setfileinfo;
+       ops.qfileinfo_fn = pvfs_qfileinfo;
+       ops.fsinfo_fn = pvfs_fsinfo;
+       ops.lpq_fn = pvfs_lpq;
+       ops.search_first_fn = pvfs_search_first;
+       ops.search_next_fn = pvfs_search_next;
+       ops.search_close_fn = pvfs_search_close;
+       ops.trans_fn = pvfs_trans;
+       ops.logoff_fn = pvfs_logoff;
+       ops.async_setup_fn = pvfs_async_setup;
+       ops.cancel_fn = pvfs_cancel;
+       ops.notify_fn = pvfs_notify;
 
        /* register ourselves with the NTVFS subsystem. We register
           under the name 'default' as we wish to be the default
           backend, and also register as 'posix' */
        ops.name = "default";
 
        /* register ourselves with the NTVFS subsystem. We register
           under the name 'default' as we wish to be the default
           backend, and also register as 'posix' */
        ops.name = "default";
-       ret = ntvfs_register(&ops);
+       ret = ntvfs_register(&ops, &vers);
+
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name));
+       }
 
        ops.name = "posix";
 
        ops.name = "posix";
-       ret = ntvfs_register(&ops);
+       ret = ntvfs_register(&ops, &vers);
 
        if (!NT_STATUS_IS_OK(ret)) {
 
        if (!NT_STATUS_IS_OK(ret)) {
-               DEBUG(0,("Failed to register POSIX backend!\n"));
+               DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name));
+       }
+
+       if (NT_STATUS_IS_OK(ret)) {
+               ret = ntvfs_common_init();
        }
 
        return ret;
        }
 
        return ret;