summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-05-28 22:07:55 +0200
committerThomas Haller <thaller@redhat.com>2015-07-29 22:34:35 +0200
commitb5cc017ba473de011881e40b26b3ee3433f1567c (patch)
tree8f93f3a47930719b0e8488011044222bb16f1648
parentbce040daa2399688b437ac5609339f3d3e1b17b8 (diff)
downloadNetworkManager-b5cc017ba473de011881e40b26b3ee3433f1567c.tar.gz
libnm: add _nm_utils_check_module_file()
-rw-r--r--libnm-core/nm-core-internal.h6
-rw-r--r--libnm-core/nm-utils.c84
2 files changed, 90 insertions, 0 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index b1fb61b544..ea095a6510 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -143,6 +143,12 @@ gboolean _nm_utils_check_file (const char *filename,
struct stat *out_st,
GError **error);
+char *_nm_utils_check_module_file (const char *name,
+ int check_owner,
+ NMUtilsCheckFilePredicate check_file,
+ gpointer user_data,
+ GError **error);
+
#define NM_UTILS_UUID_TYPE_LEGACY 0
#define NM_UTILS_UUID_TYPE_VARIANT3 1
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 91bde5059e..2cc6ed3955 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -2478,6 +2478,90 @@ _nm_utils_check_file (const char *filename,
return TRUE;
}
+
+static char *
+_resolve_module_file_name (const char *file_name)
+{
+ char *name = NULL;
+
+ /* g_module_open() is searching for the exact file to load,
+ * but it doesn't give us a hook to check file permissions
+ * and ownership. Reimplement the file name resolution.
+ *
+ * Copied from g_module_open(). */
+
+ /* check whether we have a readable file right away */
+ if (g_file_test (file_name, G_FILE_TEST_IS_REGULAR))
+ name = g_strdup (file_name);
+
+ /* try completing file name with standard library suffix */
+ if ( !name
+ && !g_str_has_suffix (file_name, "." G_MODULE_SUFFIX)) {
+ name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL);
+ if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) {
+ g_free (name);
+ name = NULL;
+ }
+ }
+
+ /* g_module_open() would also try appending ".la". We don't do that
+ * because we require the user to specify a shared library (directly). */
+
+ return name;
+}
+
+char *
+_nm_utils_check_module_file (const char *name,
+ int check_owner,
+ NMUtilsCheckFilePredicate check_file,
+ gpointer user_data,
+ GError **error)
+{
+ gs_free char *name_resolved = NULL;
+ char *s;
+
+ if (!g_path_is_absolute (name)) {
+ g_set_error (error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_FAILED,
+ _("path is not absolute (%s)"), name);
+ return NULL;
+ }
+
+ name_resolved = _resolve_module_file_name (name);
+
+ if (!name_resolved) {
+ g_set_error (error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_FAILED,
+ _("could not resolve plugin path (%s)"), name);
+ return NULL;
+ }
+
+ if (g_str_has_suffix (name_resolved, ".la")) {
+ /* g_module_open() treats files that end with .la special.
+ * We don't want to parse the libtool archive. Just error out. */
+ g_set_error (error,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_FAILED,
+ _("libtool archives are not supported (%s)"), name_resolved);
+ return NULL;
+ }
+
+ if (!_nm_utils_check_file (name_resolved,
+ check_owner,
+ check_file,
+ user_data,
+ NULL,
+ error)) {
+ return NULL;
+ }
+
+ s = name_resolved;
+ name_resolved = NULL;
+ return s;
+}
+
/**********************************************************************************************/
/**