diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/vfs.c | 103 |
1 files changed, 58 insertions, 45 deletions
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index cdff26ed1e..a8b350b9cd 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -196,21 +196,72 @@ static void vfs_init_default(connection_struct *conn) conn->vfs_private = NULL; } +/*************************************************************************** + Function to load old VFS modules. Should go away after a while. + **************************************************************************/ + +static BOOL vfs_load_old_plugin(connection_struct *conn, const char *vfs_object) +{ + int vfs_version = -1; + vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *); + /* Open object file */ + + 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; + } + + /* Get handle on vfs_init() symbol */ + + init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init"); + + if (init_fptr == NULL) { + DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object)); + 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; + } + + return True; +} + + + /**************************************************************************** initialise custom vfs hooks -****************************************************************************/ + ****************************************************************************/ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) { - int vfs_version = -1; - vfs_op_tuple *ops, *(*init_fptr)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *); - int i; + vfs_op_tuple *ops; + int i; struct vfs_init_function_entry *entry; DEBUG(3, ("Initialising custom vfs hooks from %s\n", vfs_object)); 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) && @@ -220,52 +271,14 @@ BOOL vfs_init_custom(connection_struct *conn, const char *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) */ - - /* Open object file */ - - 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; - } - - /* Get handle on vfs_init() symbol */ - - init_fptr = (vfs_op_tuple *(*)(int *, const struct vfs_ops *, struct smb_vfs_handle_struct *))sys_dlsym(conn->vfs_private->handle, "vfs_init"); - - if (init_fptr == NULL) { - DEBUG(0, ("No vfs_init() symbol found in %s\n", vfs_object)); - 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; - } + DEBUG(2, ("Can't load module with new modules system, falling back to old\n")); + if (!vfs_load_old_plugin(conn, vfs_object)) return False; } for(i=0; ops[i].op != NULL; i++) { |