NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tuples) { struct vfs_init_function_entry *entry = backends; if ((version != SMB_VFS_INTERFACE_VERSION)) { DEBUG(0, ("Failed to register vfs module.\n" "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n" "current SMB_VFS_INTERFACE_VERSION is %d.\n" "Please recompile against the current Samba Version!\n", version, SMB_VFS_INTERFACE_VERSION)); return NT_STATUS_OBJECT_TYPE_MISMATCH; } if (!name || !name[0] || !vfs_op_tuples) { DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n")); return NT_STATUS_INVALID_PARAMETER; } if (vfs_find_backend_entry(name)) { DEBUG(0,("VFS module %s already loaded!\n", name)); return NT_STATUS_OBJECT_NAME_COLLISION; } entry = SMB_XMALLOC_P(struct vfs_init_function_entry); entry->name = smb_xstrdup(name); entry->vfs_op_tuples = vfs_op_tuples; DLIST_ADD(backends, entry); DEBUG(5, ("Successfully added vfs backend '%s'\n", name)); return NT_STATUS_OK; }
BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object) { vfs_op_tuple *ops; char *module_name = NULL; char *module_param = NULL, *p; int i; vfs_handle_struct *handle; struct vfs_init_function_entry *entry; if (!conn||!vfs_object||!vfs_object[0]) { DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n")); return False; } if(!backends) { static_init_vfs; } DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object)); module_name = smb_xstrdup(vfs_object); p = strchr_m(module_name, ':'); if (p) { *p = 0; module_param = p+1; trim_char(module_param, ' ', ' '); } trim_char(module_name, ' ', ' '); /* First, try to load the module with the new module system */ if((entry = vfs_find_backend_entry(module_name)) || (NT_STATUS_IS_OK(smb_probe_module("vfs", module_name)) && (entry = vfs_find_backend_entry(module_name)))) { DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object)); if ((ops = entry->vfs_op_tuples) == NULL) { DEBUG(0, ("entry->vfs_op_tuples==NULL for [%s] failed\n", vfs_object)); SAFE_FREE(module_name); return False; } } else { DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object)); SAFE_FREE(module_name); return False; } handle = TALLOC_ZERO_P(conn->mem_ctx,vfs_handle_struct); if (!handle) { DEBUG(0,("TALLOC_ZERO() failed!\n")); SAFE_FREE(module_name); return False; } memcpy(&handle->vfs_next, &conn->vfs, sizeof(struct vfs_ops)); handle->conn = conn; if (module_param) { handle->param = talloc_strdup(conn->mem_ctx, module_param); } DLIST_ADD(conn->vfs_handles, handle); for(i=0; ops[i].op != NULL; i++) { DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer)); if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) { /* If this operation was already made opaque by different module, it * will be overridden here. */ DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object)); vfs_set_operation(&conn->vfs_opaque, ops[i].type, handle, ops[i].op); } /* Change current VFS disposition*/ DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object)); vfs_set_operation(&conn->vfs, ops[i].type, handle, ops[i].op); } SAFE_FREE(module_name); return True; }
bool vfs_init_custom(connection_struct *conn, const char *vfs_object) { char *module_path = NULL; char *module_name = NULL; char *module_param = NULL, *p; vfs_handle_struct *handle; const struct vfs_init_function_entry *entry; if (!conn||!vfs_object||!vfs_object[0]) { DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n")); return False; } if(!backends) { static_init_vfs; } DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object)); module_path = smb_xstrdup(vfs_object); p = strchr_m(module_path, ':'); if (p) { *p = 0; module_param = p+1; trim_char(module_param, ' ', ' '); } trim_char(module_path, ' ', ' '); module_name = smb_xstrdup(module_path); if ((module_name[0] == '/') && (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) { /* * Extract the module name from the path. Just use the base * name of the last path component. */ SAFE_FREE(module_name); module_name = smb_xstrdup(strrchr_m(module_path, '/')+1); p = strchr_m(module_name, '.'); if (p != NULL) { *p = '\0'; } } /* First, try to load the module with the new module system */ entry = vfs_find_backend_entry(module_name); if (!entry) { NTSTATUS status; DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n", vfs_object)); status = smb_probe_module("vfs", module_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("error probing vfs module '%s': %s\n", module_path, nt_errstr(status))); goto fail; } entry = vfs_find_backend_entry(module_name); if (!entry) { DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object)); goto fail; } } DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object)); handle = TALLOC_ZERO_P(conn, vfs_handle_struct); if (!handle) { DEBUG(0,("TALLOC_ZERO() failed!\n")); goto fail; } handle->conn = conn; handle->fns = entry->fns; if (module_param) { handle->param = talloc_strdup(conn, module_param); } DLIST_ADD(conn->vfs_handles, handle); SAFE_FREE(module_path); SAFE_FREE(module_name); return True; fail: SAFE_FREE(module_path); SAFE_FREE(module_name); return False; }