QUOTAOBJS=@QUOTAOBJS@
-VFS_MODULES = bin/vfs_audit.@SHLIBEXT@ bin/vfs_extd_audit.@SHLIBEXT@ bin/vfs_recycle.@SHLIBEXT@ \
- bin/vfs_netatalk.@SHLIBEXT@ bin/vfs_fake_perms.@SHLIBEXT@
+VFS_MODULES = @VFS_MODULES@
PDB_MODULES = @PDB_MODULES@
RPC_MODULES = @RPC_MODULES@
CHARSET_MODULES = @CHARSET_MODULES@
smbd/change_trust_pw.o \
$(MANGLE_OBJ)
-SMBD_OBJ_BASE = $(SMBD_OBJ_SRV) $(MSDFS_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \
+SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(MSDFS_OBJ) $(LIBSMB_OBJ) \
+ $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) $(UBIQX_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) \
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
MSDFS_OBJ = msdfs/msdfs.o
-SMBD_OBJ = $(SMBD_OBJ_MAIN) $(SMBD_OBJ_BASE)
-
+SMBD_OBJ = $(SMBD_OBJ_BASE) $(SMBD_OBJ_MAIN)
NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \
nmbd/nmbd_browsesync.o nmbd/nmbd_elections.o \
# now the rules...
######################################################################
all : SHOWFLAGS proto_exists $(SBIN_PROGS) $(BIN_PROGS) $(SHLIBS) \
- $(TORTURE_PROGS) @EXTRA_ALL_TARGETS@
+ $(TORTURE_PROGS) $(MODULES) @EXTRA_ALL_TARGETS@
pam_smbpass : SHOWFLAGS bin/pam_smbpass.@SHLIBEXT@
@$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ) @XML_LIBS@ \
@SONAMEFLAG@`basename $@`
-bin/vfs_audit.@SHLIBEXT@: $(VFS_AUDIT_OBJ)
+bin/audit.@SHLIBEXT@: $(VFS_AUDIT_OBJ)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AUDIT_OBJ) \
@SONAMEFLAG@`basename $@`
-bin/vfs_extd_audit.@SHLIBEXT@: $(VFS_EXTD_AUDIT_OBJ)
+bin/extd_audit.@SHLIBEXT@: $(VFS_EXTD_AUDIT_OBJ)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AUDIT_OBJ) \
@SONAMEFLAG@`basename $@`
-bin/vfs_recycle.@SHLIBEXT@: $(VFS_RECYCLE_OBJ)
+bin/recycle.@SHLIBEXT@: $(VFS_RECYCLE_OBJ)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_RECYCLE_OBJ) \
@SONAMEFLAG@`basename $@`
-bin/vfs_netatalk.@SHLIBEXT@: $(VFS_NETATALK_OBJ)
+bin/netatalk.@SHLIBEXT@: $(VFS_NETATALK_OBJ)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_NETATALK_OBJ) \
@SONAMEFLAG@`basename $@`
-bin/vfs_fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ)
+bin/fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_FAKE_PERMS_OBJ) \
@SONAMEFLAG@`basename $@`
bin/t_stringoverflow@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_stringoverflow.o
$(CC) $(FLAGS) -o $@ torture/t_stringoverflow.o -L./bin -lbigballofmud
-install: installbin installman installscripts installdat installswat
+install: installbin installman installscripts installdat installswat installmodules
# DESTDIR is used here to prevent packagers wasting their time
# duplicating the Makefile. Remove it and you will have the privelege
SMB_MODULE(vfs_netatalk, \$(VFS_NETATALK), bin/netatalk.so, VFS)
SMB_SUBSYSTEM(VFS)
+SMB_MODULE(vfs_recycle, \$(VFS_RECYCLE_OBJ), bin/recycle.so, VFS)
+SMB_MODULE(vfs_audit, \$(VFS_AUDIT_OBJ), bin/audit.so, VFS)
+SMB_MODULE(vfs_extd_audit, \$(VFS_EXTD_AUDIT_OBJ), bin/extd_audit.so, VFS)
+SMB_MODULE(vfs_fake_perms, \$(VFS_FAKE_PERMS_OBJ), bin/fake_perms.so, VFS)
+SMB_MODULE(vfs_netatalk, \$(VFS_NETATALK), bin/netatalk.so, VFS)
+SMB_SUBSYSTEM(VFS)
+
AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
AC_SUBST(MODULES_CLEAN)
#define SMB_VFS_INTERFACE_VERSION 5
-/* Version of supported cascaded interface backward copmatibility.
+/* Version of supported cascaded interface backward compatibility.
(version 5 corresponds to SMB_VFS_INTERFACE_VERSION 5)
It is used in vfs_init_custom() to detect VFS modules which conform to cascaded
VFS interface but implement elder version than current version of Samba uses.
is unloaded from smbd process using sys_dlclose().
Prototypes:
- vfs_op_tuple *vfs_init(int *vfs_version, const struct vfs_ops *def_vfs_ops,
+ vfs_op_tuple *vfs_init(const struct vfs_ops *def_vfs_ops,
struct smb_vfs_handle_struct *vfs_handle);
void vfs_done(connection_struct *conn);
/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
+static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops,
struct smb_vfs_handle_struct *vfs_handle)
{
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
audit_handle = vfs_handle;
return audit_ops;
}
-/* VFS finalization function. */
-void vfs_done(connection_struct *conn)
-{
- syslog(SYSLOG_PRIORITY, "VFS_DONE: vfs module unloaded\n");
-}
-
/* Implementation of vfs_ops. Pass everything on to the default
operation but log event first. */
return result;
}
+
+int vfs_audit_init(void)
+{
+ return smb_register_vfs("audit", audit_init, SMB_VFS_INTERFACE_VERSION);
+}
/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
+static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops,
struct smb_vfs_handle_struct *vfs_handle)
{
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
audit_handle = vfs_handle;
return audit_ops;
}
-/* VFS finalization function. */
-
-void vfs_done(connection_struct *conn)
-{
- syslog(SYSLOG_PRIORITY, "VFS_DONE: vfs module unloaded\n");
-}
-
/* Implementation of vfs_ops. Pass everything on to the default
operation but log event first. */
return result;
}
+
+int vfs_extd_audit_init(void)
+{
+ return smb_register_vfs("extd_audit", audit_init, SMB_VFS_INTERFACE_VERSION);
+}
/* VFS initialisation - return initialized vfs_op_tuple array back to Samba */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
+static vfs_op_tuple *fake_perms_init(const struct vfs_ops *def_vfs_ops,
struct smb_vfs_handle_struct *vfs_handle)
{
DEBUG(3, ("Initialising default vfs hooks\n"));
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
/* Remember vfs_handle for further allocation and referencing of private
return fake_perms_ops;
}
-/* VFS finalization function */
-void vfs_done(connection_struct *conn)
+int vfs_fake_perms_init(void)
{
- DEBUG(3, ("Finalizing default vfs hooks\n"));
+ return smb_register_vfs("fake_perms", fake_perms_init, SMB_VFS_INTERFACE_VERSION);
}
};
/* VFS initialisation function. Return vfs_op_tuple array back to SAMBA. */
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
+static vfs_op_tuple *netatalk_init(const struct vfs_ops *def_vfs_ops,
struct smb_vfs_handle_struct *vfs_handle)
{
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
atalk_handle = vfs_handle;
return atalk_ops;
}
-/* VFS finalization function. */
-void vfs_done(connection_struct *conn)
+int vfs_netatalk_init(void)
{
- DEBUG(3, ("ATALK: vfs module unloaded\n"));
+ return smb_register_vfs("netatalk", netatalk_init, SMB_VFS_INTERFACE_VERSION);
}
*
* @retval initialised vfs_op_tuple array
**/
-vfs_op_tuple *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops,
+static vfs_op_tuple *recycle_init(const struct vfs_ops *def_vfs_ops,
struct smb_vfs_handle_struct *vfs_handle)
{
TALLOC_CTX *mem_ctx = NULL;
DEBUG(10, ("Initializing VFS module recycle\n"));
- *vfs_version = SMB_VFS_INTERFACE_VERSION;
memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
vfs_recycle_debug_level = debug_add_class("vfs_recycle_bin");
if (vfs_recycle_debug_level == -1) {
return recycle_ops;
}
-/**
- * VFS finalization function.
- *
- **/
-void vfs_done(void)
-{
- recycle_bin_private_data *recdata;
- recycle_bin_connections *recconn;
-
- DEBUG(10, ("Unloading/Cleaning VFS module recycle bin\n"));
-
- if (recycle_bin_private_handle)
- recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
- else {
- DEBUG(0, ("Recycle bin not initialized!\n"));
- return;
- }
-
- if (recdata) {
- if (recdata->conns) {
- recconn = recdata->conns;
- while (recconn) {
- talloc_destroy(recconn->data->mem_ctx);
- recconn = recconn->next;
- }
- }
- if (recdata->mem_ctx) {
- talloc_destroy(recdata->mem_ctx);
- }
- recdata = NULL;
- }
-}
-
static int recycle_connect(struct connection_struct *conn, const char *service, const char *user)
{
TALLOC_CTX *ctx = NULL;
SAFE_FREE(final_name);
return rc;
}
+
+int vfs_recycle_init(void)
+{
+ return smb_register_vfs("recycle", recycle_init, SMB_VFS_INTERFACE_VERSION);
+}
Main SMB server routines
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Martin Pool 2002
- Copyright (C) Jelmer Vernooij 2002
+ Copyright (C) Jelmer Vernooij 2002-2003
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
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
+struct vfs_init_function_entry {
+ char *name;
+ vfs_op_tuple *ops, *(*init)(const struct vfs_ops *, struct smb_vfs_handle_struct *);
+ struct vfs_init_function_entry *prev, *next;
+};
+
+static struct vfs_init_function_entry *backends = NULL;
/* Some structures to help us initialise the vfs operations table */
vfswrap_sys_acl_free_qualifier
};
+/****************************************************************************
+ maintain the list of available backends
+****************************************************************************/
+
+struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
+{
+ struct vfs_init_function_entry *entry = backends;
+
+ while(entry) {
+ if (strequal(entry->name, name)) return entry;
+ entry = entry->next;
+ }
+
+ return NULL;
+}
+
+BOOL smb_register_vfs(const char *name, vfs_op_tuple *(*init)(const struct vfs_ops *, struct smb_vfs_handle_struct *), int version)
+{
+ struct vfs_init_function_entry *entry = backends;
+
+ if ((version < SMB_VFS_INTERFACE_CASCADED)) {
+ DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n",
+ version, SMB_VFS_INTERFACE_VERSION ));
+ return False;
+ }
+
+ if ((version < SMB_VFS_INTERFACE_VERSION)) {
+ DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\
+ Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n",
+ version, SMB_VFS_INTERFACE_VERSION, version ));
+ return False;
+ }
+
+ while(entry) {
+ if (strequal(entry->name, name)) {
+ DEBUG(0,("VFS module %s already loaded!\n", name));
+ return False;
+ }
+ entry = entry->next;
+ }
+
+ entry = smb_xmalloc(sizeof(struct vfs_init_function_entry));
+ entry->name = smb_xstrdup(name);
+ entry->init = init;
+
+ DLIST_ADD(backends, entry);
+ DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
+ return True;
+}
+
/****************************************************************************
initialise default vfs hooks
****************************************************************************/
int vfs_version = -1;
vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *);
int i;
+ struct vfs_init_function_entry *entry;
DEBUG(3, ("Initialising custom vfs hooks from %s\n", vfs_object));
- /* Open object file */
+ if(!backends) static_init_vfs;
+
+ /* First, try to load the module with the new module system */
+ if((entry = vfs_find_backend_entry(vfs_object)) ||
+ (smb_probe_module("vfs", vfs_object) &&
+ (entry = vfs_find_backend_entry(vfs_object)))) {
+
+ DEBUG(0,("Successfully loaded %s with the new modules system\n", vfs_object));
+
+ if ((ops = entry->init(&conn->vfs_ops, conn->vfs_private)) == NULL) {
+ DEBUG(0, ("vfs init function from %s failed\n", vfs_object));
+ sys_dlclose(conn->vfs_private->handle);
+ return False;
+ }
+ } else {
+ /* If that doesn't work, fall back to the old system
+ * (This part should go away after a while, it's only here
+ * for backwards compatibility) */
- if ((conn->vfs_private->handle = sys_dlopen(vfs_object, RTLD_NOW)) == NULL) {
- DEBUG(0, ("Error opening %s: %s\n", vfs_object, sys_dlerror()));
- return False;
- }
+ /* Open object file */
- /* Get handle on vfs_init() symbol */
+ if ((conn->vfs_private->handle = sys_dlopen(vfs_object, RTLD_NOW)) == NULL) {
+ DEBUG(0, ("Error opening %s: %s\n", vfs_object, sys_dlerror()));
+ return False;
+ }
- init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init");
+ /* Get handle on vfs_init() symbol */
- if (init_fptr == NULL) {
- DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object));
- sys_dlclose(conn->vfs_private->handle);
- return False;
- }
+ init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init");
- /* Initialise vfs_ops structure */
+ if (init_fptr == NULL) {
+ DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object));
+ sys_dlclose(conn->vfs_private->handle);
+ return False;
+ }
- if ((ops = init_fptr(&vfs_version, &conn->vfs_ops, conn->vfs_private)) == NULL) {
- DEBUG(0, ("vfs_init() function from %s failed\n", vfs_object));
- sys_dlclose(conn->vfs_private->handle);
- return False;
- }
-
- if ((vfs_version < SMB_VFS_INTERFACE_CASCADED)) {
- DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n",
- vfs_version, SMB_VFS_INTERFACE_VERSION ));
- sys_dlclose(conn->vfs_private->handle);
- return False;
- }
-
- if ((vfs_version < SMB_VFS_INTERFACE_VERSION)) {
- DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\
-Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n",
- vfs_version, SMB_VFS_INTERFACE_VERSION, vfs_version ));
- sys_dlclose(conn->vfs_private->handle);
- return False;
- }
+ /* Initialise vfs_ops structure */
+ if ((ops = init_fptr(&vfs_version, &conn->vfs_ops, conn->vfs_private)) == NULL) {
+ DEBUG(0, ("vfs_init() function from %s failed\n", vfs_object));
+ sys_dlclose(conn->vfs_private->handle);
+ return False;
+ }
+
+ if ((vfs_version < SMB_VFS_INTERFACE_CASCADED)) {
+ DEBUG(0, ("vfs_init() returned wrong interface version info (was %d, should be no less than %d)\n",
+ vfs_version, SMB_VFS_INTERFACE_VERSION ));
+ sys_dlclose(conn->vfs_private->handle);
+ return False;
+ }
+
+ if ((vfs_version < SMB_VFS_INTERFACE_VERSION)) {
+ DEBUG(0, ("Warning: vfs_init() states that module confirms interface version #%d, current interface version is #%d.\n\
+ Proceeding in compatibility mode, new operations (since version #%d) will fallback to default ones.\n",
+ vfs_version, SMB_VFS_INTERFACE_VERSION, vfs_version ));
+ sys_dlclose(conn->vfs_private->handle);
+ return False;
+ }
+ }
for(i=0; ops[i].op != NULL; i++) {
DEBUG(3, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer));