diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 082ebc9e28..8d97b066ee 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -72,6 +72,7 @@ #include "nm-utils.h" #include "nm-vpn-dbus-interface.h" #include "nm-core-types-internal.h" +#include "nm-vpn-editor-plugin.h" /* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated * connection can be replaced by a already-defined connection. This flag only @@ -245,6 +246,14 @@ GSList *_nm_vpn_plugin_info_list_load_dir (const char *dirname, NMUtilsCheckFilePredicate check_file, gpointer user_data); +NMVpnEditorPlugin * _nm_vpn_editor_plugin_load (const char *plugin_filename, + gboolean force_absolute_path, + const char *check_service, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error); + /***********************************************************/ typedef struct { diff --git a/libnm-core/nm-vpn-editor-plugin.c b/libnm-core/nm-vpn-editor-plugin.c index e1c2f450ef..32f6cbcdde 100644 --- a/libnm-core/nm-vpn-editor-plugin.c +++ b/libnm-core/nm-vpn-editor-plugin.c @@ -71,56 +71,55 @@ nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface) /*********************************************************************/ -/** - * nm_vpn_editor_plugin_load_from_file: - * @plugin_filename: The path to the share library to load. - * The path must be an absolute filename to an existing file. - * @check_service: if not-null, check that the loaded plugin advertises - * the given service. - * @check_owner: if non-negative, check whether the file is owned - * by UID @check_owner or by root. In this case also check that - * the file is not writable by anybody else. - * @check_file: (scope call): optional callback to validate the file prior to - * loading the shared library. - * @user_data: user data for @check_file - * @error: on failure the error reason. - * - * Load the shared libary @plugin_filename and create a new - * #NMVpnEditorPlugin instace via the #NMVpnEditorPluginFactory - * function. - * - * Returns: (transfer full): a new plugin instance or %NULL on error. - * - * Since: 1.2 - */ NMVpnEditorPlugin * -nm_vpn_editor_plugin_load_from_file (const char *plugin_filename, - const char *check_service, - int check_owner, - NMUtilsCheckFilePredicate check_file, - gpointer user_data, - GError **error) +_nm_vpn_editor_plugin_load (const char *plugin_filename, + gboolean force_absolute_filename, + const char *check_service, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error) { GModule *module = NULL; gs_free_error GError *local = NULL; NMVpnEditorPluginFactory factory = NULL; NMVpnEditorPlugin *editor_plugin = NULL; + gboolean search_lib = FALSE; g_return_val_if_fail (plugin_filename && *plugin_filename, NULL); + if ( !force_absolute_filename + && !strchr (plugin_filename, '/') + && !g_str_has_suffix (plugin_filename, ".la")) { + /* we allow omitting the (absolute) path. + * + * If the @plugin_filename contains no '/', we skip any checks + * for the file and pass it directly to g_module_open()/dlopen(). + * One exception is that we don't allow for the "la" suffix. The + * reason is that g_module_open() interprets files with this extension + * special and we don't want that. */ + search_lib = TRUE; + } + /* _nm_utils_check_module_file() fails with ENOENT if the plugin file * does not exist. That is relevant, because nm-applet checks for that. */ - if (_nm_utils_check_module_file (plugin_filename, - check_owner, - check_file, - user_data, - &local)) + if ( search_lib + || _nm_utils_check_module_file (plugin_filename, + check_owner, + check_file, + user_data, + &local)) module = g_module_open (plugin_filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); if (!module) { if (local) { g_propagate_error (error, local); local = NULL; + } else if (search_lib) { + g_set_error (error, + G_FILE_ERROR, + G_FILE_ERROR_NOENT, + _("Plugin does not exist (%s)"), plugin_filename); } else { g_set_error (error, NM_VPN_PLUGIN_ERROR, @@ -197,6 +196,45 @@ nm_vpn_editor_plugin_load_from_file (const char *plugin_filename, return editor_plugin; } +/** + * nm_vpn_editor_plugin_load_from_file: + * @plugin_filename: The path to the share library to load. + * The path must be an absolute filename to an existing file. + * @check_service: if not-null, check that the loaded plugin advertises + * the given service. + * @check_owner: if non-negative, check whether the file is owned + * by UID @check_owner or by root. In this case also check that + * the file is not writable by anybody else. + * @check_file: (scope call): optional callback to validate the file prior to + * loading the shared library. + * @user_data: user data for @check_file + * @error: on failure the error reason. + * + * Load the shared libary @plugin_filename and create a new + * #NMVpnEditorPlugin instace via the #NMVpnEditorPluginFactory + * function. + * + * Returns: (transfer full): a new plugin instance or %NULL on error. + * + * Since: 1.2 + */ +NMVpnEditorPlugin * +nm_vpn_editor_plugin_load_from_file (const char *plugin_filename, + const char *check_service, + int check_owner, + NMUtilsCheckFilePredicate check_file, + gpointer user_data, + GError **error) +{ + return _nm_vpn_editor_plugin_load (plugin_filename, + TRUE, + check_service, + check_owner, + check_file, + user_data, + error); +} + /*********************************************************************/ /** diff --git a/libnm-core/nm-vpn-plugin-info.c b/libnm-core/nm-vpn-plugin-info.c index 2e6275e341..6c77f3c142 100644 --- a/libnm-core/nm-vpn-plugin-info.c +++ b/libnm-core/nm-vpn-plugin-info.c @@ -752,12 +752,13 @@ nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *self, GError **error) } priv->editor_plugin_loaded = TRUE; - priv->editor_plugin = nm_vpn_editor_plugin_load_from_file (plugin_filename, - priv->service, - getuid (), - NULL, - NULL, - error); + priv->editor_plugin = _nm_vpn_editor_plugin_load (plugin_filename, + FALSE, + priv->service, + getuid (), + NULL, + NULL, + error); return priv->editor_plugin; }