diff options
Diffstat (limited to 'src/settings/plugins/keyfile/nms-keyfile-reader.c')
| -rw-r--r-- | src/settings/plugins/keyfile/nms-keyfile-reader.c | 93 |
1 files changed, 63 insertions, 30 deletions
diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.c b/src/settings/plugins/keyfile/nms-keyfile-reader.c index cb4b8379..580a857a 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-reader.c +++ b/src/settings/plugins/keyfile/nms-keyfile-reader.c @@ -28,6 +28,7 @@ #include "nm-keyfile-internal.h" #include "NetworkManagerUtils.h" +#include "nms-keyfile-utils.h" /*****************************************************************************/ @@ -102,53 +103,87 @@ _handler_read (GKeyFile *keyfile, NMConnection * nms_keyfile_reader_from_keyfile (GKeyFile *key_file, const char *filename, + const char *base_dir, + const char *profile_dir, gboolean verbose, GError **error) { + NMConnection *connection; HandlerReadData data = { .verbose = verbose, }; + gs_free char *base_dir_free = NULL; + gs_free char *profile_filename_free = NULL; + gs_free char *filename_id = NULL; + const char *profile_filename = NULL; + + nm_assert (filename && filename[0]); + nm_assert (!base_dir || base_dir[0] == '/'); + nm_assert (!profile_dir || profile_dir[0] == '/'); + + if (base_dir) + nm_assert (!strchr (filename, '/')); + else { + const char *s; + + nm_assert (filename[0] == '/'); + + /* @base_dir may be NULL, in which case @filename must be an absolute path, + * and the directory is taken as the @base_dir. */ + s = strrchr (filename, '/'); + base_dir = nm_strndup_a (255, filename, s - filename, &base_dir_free); + if ( !profile_dir + || nm_streq (base_dir, profile_dir)) + profile_filename = filename; + filename = &s[1]; + } + + connection = nm_keyfile_read (key_file, base_dir, _handler_read, &data, error); + if (!connection) + return NULL; + + if (g_str_has_suffix (filename, NMS_KEYFILE_PATH_SUFFIX_NMCONNECTION)) { + gsize l = strlen (filename); - return nm_keyfile_read (key_file, filename, NULL, _handler_read, &data, error); + if (l > NM_STRLEN (NMS_KEYFILE_PATH_SUFFIX_NMCONNECTION)) + filename_id = g_strndup (filename, l - NM_STRLEN (NMS_KEYFILE_PATH_SUFFIX_NMCONNECTION)); + } + + nm_keyfile_read_ensure_id (connection, filename_id ?: filename); + + if (!profile_filename) { + profile_filename_free = g_build_filename (profile_dir ?: base_dir, filename, NULL); + profile_filename = profile_filename_free; + } + nm_keyfile_read_ensure_uuid (connection, profile_filename); + + return connection; } NMConnection * -nms_keyfile_reader_from_file (const char *filename, GError **error) +nms_keyfile_reader_from_file (const char *full_filename, + const char *profile_dir, + GError **error) { - GKeyFile *key_file; - struct stat statbuf; + gs_unref_keyfile GKeyFile *key_file = NULL; NMConnection *connection = NULL; GError *verify_error = NULL; - if (stat (filename, &statbuf) != 0 || !S_ISREG (statbuf.st_mode)) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "File did not exist or was not a regular file"); - return NULL; - } + nm_assert (full_filename && full_filename[0] == '/'); + nm_assert (!profile_dir || profile_dir[0] == '/'); - if (!NM_FLAGS_HAS (nm_utils_get_testing (), NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK)) { - if (statbuf.st_mode & 0077) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "File permissions (%o) were insecure", - statbuf.st_mode); - return NULL; - } - - if (statbuf.st_uid != 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "File owner (%o) is insecure", - statbuf.st_mode); - return NULL; - } - } + if (!nms_keyfile_utils_check_file_permissions (full_filename, + NULL, + error)) + return NULL; key_file = g_key_file_new (); - if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error)) - goto out; + if (!g_key_file_load_from_file (key_file, full_filename, G_KEY_FILE_NONE, error)) + return NULL; - connection = nms_keyfile_reader_from_keyfile (key_file, filename, TRUE, error); + connection = nms_keyfile_reader_from_keyfile (key_file, full_filename, NULL, profile_dir, TRUE, error); if (!connection) - goto out; + return NULL; /* Normalize and verify the connection */ if (!nm_connection_normalize (connection, NULL, NULL, &verify_error)) { @@ -160,8 +195,6 @@ nms_keyfile_reader_from_file (const char *filename, GError **error) connection = NULL; } -out: - g_key_file_free (key_file); return connection; } |