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 most of the POSIX NTVFS backend
#include "includes.h"
#include "vfs_posix.h"
-#include "librpc/gen_ndr/ndr_security.h"
-#include "smbd/service_stream.h"
+#include "librpc/gen_ndr/security.h"
#include "lib/tdb/include/tdb.h"
#include "db_wrap.h"
-#include "libcli/security/proto.h"
+#include "libcli/security/security.h"
+#include "lib/events/events.h"
/*
*/
static void pvfs_setup_options(struct pvfs_state *pvfs)
{
- int snum = pvfs->ntvfs->ctx->config.snum;
+ struct share_config *scfg = pvfs->ntvfs->ctx->config;
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)) {
+ 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;
- }
-
+ if (share_bool_option(scfg, PVFS_AIO, false))
+ pvfs->flags |= PVFS_FLAG_LINUX_AIO;
+
+ /* 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 */
- 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 (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
- 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->share_name = talloc_strdup(pvfs, scfg->name);
pvfs->fs_attribs =
FS_ATTR_CASE_SENSITIVE_SEARCH |
FS_ATTR_SPARSE_FILES;
/* allow xattrs to be stored in a external tdb */
- eadb = lp_parm_string(snum, "posix", "eadb");
+ eadb = share_string_option(scfg, PVFS_EADB, NULL);
if (eadb != NULL) {
pvfs->ea_db = tdb_wrap_open(pvfs, eadb, 50000,
TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) {
pvfs_xattr_probe(pvfs);
}
+
+ /* enable an ACL backend */
+ pvfs->acl_ops = pvfs_acl_backend_byname(share_string_option(scfg, PVFS_ACL, "xattr"));
}
+static int pvfs_state_destructor(struct pvfs_state *pvfs)
+{
+ struct pvfs_file *f, *fn;
+ struct pvfs_search_state *s, *sn;
+
+ /*
+ * make sure we cleanup files and searches before anything else
+ * because there destructors need to acess the pvfs_state struct
+ */
+ for (f=pvfs->files.list; f; f=fn) {
+ fn = f->next;
+ talloc_free(f);
+ }
+
+ for (s=pvfs->search.list; s; s=sn) {
+ sn = s->next;
+ talloc_free(s);
+ }
+
+ return 0;
+}
/*
connect to a share - used when a tree_connect operation comes
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 = talloc_strdup(pvfs, share_string_option(ntvfs->ctx->config, SHARE_PATH, ""));
NT_STATUS_HAVE_NO_MEMORY(base_directory);
if (strcmp(base_directory, "/") != 0) {
trim_string(base_directory, NULL, "/");
ntvfs->private_data = pvfs;
pvfs->brl_context = brl_init(pvfs,
- pvfs->ntvfs->ctx->server_id,
- pvfs->ntvfs->ctx->config.snum,
+ pvfs->ntvfs->ctx->server_id,
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;
}
+ /* allow this to be NULL - we just disable change notify */
+ pvfs->notify_context = notify_init(pvfs,
+ pvfs->ntvfs->ctx->server_id,
+ pvfs->ntvfs->ctx->msg_ctx,
+ event_context_find(pvfs),
+ pvfs->ntvfs->ctx->config);
+
pvfs->sidmap = sidmap_open(pvfs);
if (pvfs->sidmap == NULL) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- /* allocate the fnum id -> ptr tree */
- pvfs->idtree_fnum = idr_init(pvfs);
- NT_STATUS_HAVE_NO_MEMORY(pvfs->idtree_fnum);
-
/* allocate the search handle -> ptr tree */
- pvfs->idtree_search = idr_init(pvfs);
- NT_STATUS_HAVE_NO_MEMORY(pvfs->idtree_search);
+ pvfs->search.idtree = idr_init(pvfs);
+ NT_STATUS_HAVE_NO_MEMORY(pvfs->search.idtree);
status = pvfs_mangle_init(pvfs);
NT_STATUS_NOT_OK_RETURN(status);
pvfs_setup_options(pvfs);
+ talloc_set_destructor(pvfs, pvfs_state_destructor);
+
#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;
{
NTSTATUS ret;
struct ntvfs_ops ops;
+ NTVFS_CURRENT_CRITICAL_SIZES(vers);
ZERO_STRUCT(ops);
ops.logoff = pvfs_logoff;
ops.async_setup = pvfs_async_setup;
ops.cancel = pvfs_cancel;
+ ops.notify = 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";
- 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";
- ret = ntvfs_register(&ops);
+ ret = ntvfs_register(&ops, &vers);
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;