|
Packit Service |
5ffa24 |
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
Packit Service |
5ffa24 |
/*
|
|
Packit Service |
5ffa24 |
* Copyright (C) 2008 Novell, Inc.
|
|
Packit Service |
5ffa24 |
* Copyright (C) 2008 - 2015 Red Hat, Inc.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
2bceb2 |
#include "src/core/nm-default-daemon.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#include "nms-keyfile-writer.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#include <stdlib.h>
|
|
Packit Service |
5ffa24 |
#include <sys/stat.h>
|
|
Packit Service |
5ffa24 |
#include <unistd.h>
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
dff8e4 |
#include "libnm-core-intern/nm-keyfile-internal.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#include "nms-keyfile-utils.h"
|
|
Packit Service |
5ffa24 |
#include "nms-keyfile-reader.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
dff8e4 |
#include "libnm-glib-aux/nm-io-utils.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
typedef struct {
|
|
Packit Service |
5ffa24 |
const char *keyfile_dir;
|
|
Packit Service |
5ffa24 |
} WriteInfo;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
cert_writer(NMConnection * connection,
|
|
Packit Service |
5ffa24 |
GKeyFile * file,
|
|
Packit Service |
5ffa24 |
NMSetting8021x * setting,
|
|
Packit Service |
5ffa24 |
const NMSetting8021xSchemeVtable *vtable,
|
|
Packit Service |
5ffa24 |
WriteInfo * info,
|
|
Packit Service |
5ffa24 |
GError ** error)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
const char * setting_name = nm_setting_get_name(NM_SETTING(setting));
|
|
Packit Service |
5ffa24 |
NMSetting8021xCKScheme scheme;
|
|
Packit Service |
5ffa24 |
NMSetting8021xCKFormat format;
|
|
Packit Service |
5ffa24 |
const char * path = NULL, *ext = "pem";
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
scheme = vtable->scheme_func(setting);
|
|
Packit Service |
5ffa24 |
if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
|
|
Packit Service |
5ffa24 |
char * tmp = NULL;
|
|
Packit Service |
5ffa24 |
const char *accepted_path = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
path = vtable->path_func(setting);
|
|
Packit Service |
5ffa24 |
g_assert(path);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (g_str_has_prefix(path, info->keyfile_dir)) {
|
|
Packit Service |
5ffa24 |
const char *p = path + strlen(info->keyfile_dir);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* If the path is rooted in the keyfile directory, just use a
|
|
Packit Service |
5ffa24 |
* relative path instead of an absolute one.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
if (*p == '/') {
|
|
Packit Service |
5ffa24 |
while (*p == '/')
|
|
Packit Service |
5ffa24 |
p++;
|
|
Packit Service |
5ffa24 |
if (p[0]) {
|
|
Packit Service |
5ffa24 |
/* If @p looks like an integer list, the following detection will fail too and
|
|
Packit Service |
5ffa24 |
* we will file:// qualify the path below. We thus avoid writing a path string
|
|
Packit Service |
5ffa24 |
* that would be interpreted as legacy binary format by reader. */
|
|
Packit Service |
5ffa24 |
tmp = nm_keyfile_detect_unqualified_path_scheme(info->keyfile_dir,
|
|
Packit Service |
5ffa24 |
p,
|
|
Packit Service |
5ffa24 |
-1,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
if (tmp) {
|
|
Packit Service |
5ffa24 |
nm_clear_g_free(&tmp);
|
|
Packit Service |
5ffa24 |
accepted_path = p;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
if (!accepted_path) {
|
|
Packit Service |
5ffa24 |
/* What we are about to write, must also be understood by the reader.
|
|
Packit Service |
5ffa24 |
* Otherwise, add a file:// prefix */
|
|
Packit Service |
5ffa24 |
tmp =
|
|
Packit Service |
5ffa24 |
nm_keyfile_detect_unqualified_path_scheme(info->keyfile_dir, path, -1, FALSE, NULL);
|
|
Packit Service |
5ffa24 |
if (tmp) {
|
|
Packit Service |
5ffa24 |
nm_clear_g_free(&tmp);
|
|
Packit Service |
5ffa24 |
accepted_path = path;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!accepted_path)
|
|
Packit Service |
5ffa24 |
accepted_path = tmp = g_strconcat(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL);
|
|
Packit Service |
5ffa24 |
nm_keyfile_plugin_kf_set_string(file, setting_name, vtable->setting_key, accepted_path);
|
|
Packit Service |
5ffa24 |
g_free(tmp);
|
|
Packit Service |
5ffa24 |
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
|
|
Packit Service |
5ffa24 |
nm_keyfile_plugin_kf_set_string(file,
|
|
Packit Service |
5ffa24 |
setting_name,
|
|
Packit Service |
5ffa24 |
vtable->setting_key,
|
|
Packit Service |
5ffa24 |
vtable->uri_func(setting));
|
|
Packit Service |
5ffa24 |
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
|
|
Packit Service |
5ffa24 |
GBytes * blob;
|
|
Packit Service |
5ffa24 |
const guint8 *blob_data;
|
|
Packit Service |
5ffa24 |
gsize blob_len;
|
|
Packit Service |
5ffa24 |
gboolean success;
|
|
Packit Service |
5ffa24 |
GError * local = NULL;
|
|
Packit Service |
5ffa24 |
char * new_path;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
blob = vtable->blob_func(setting);
|
|
Packit Service |
5ffa24 |
g_assert(blob);
|
|
Packit Service |
5ffa24 |
blob_data = g_bytes_get_data(blob, &blob_len);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (vtable->format_func) {
|
|
Packit Service |
5ffa24 |
/* Get the extension for a private key */
|
|
Packit Service |
5ffa24 |
format = vtable->format_func(setting);
|
|
Packit Service |
5ffa24 |
if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
|
|
Packit Service |
5ffa24 |
ext = "p12";
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
/* DER or PEM format certificate? */
|
|
Packit Service |
5ffa24 |
if (blob_len > 2 && blob_data[0] == 0x30 && blob_data[1] == 0x82)
|
|
Packit Service |
5ffa24 |
ext = "der";
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Write the raw data out to the standard file so that we can use paths
|
|
Packit Service |
5ffa24 |
* from now on instead of pushing around the certificate data.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
new_path = g_strdup_printf("%s/%s-%s.%s",
|
|
Packit Service |
5ffa24 |
info->keyfile_dir,
|
|
Packit Service |
5ffa24 |
nm_connection_get_uuid(connection),
|
|
Packit Service |
5ffa24 |
vtable->file_suffix,
|
|
Packit Service |
5ffa24 |
ext);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* FIXME(keyfile-parse-in-memory): writer must not access/write to the file system before
|
|
Packit Service |
5ffa24 |
* being sure that the entire profile can be written and all circumstances are good to
|
|
Packit Bot |
c44df3 |
* proceed. That means, while writing we must only collect the blobs in-memory, and write
|
|
Packit Service |
5ffa24 |
* them all in the end together (or not at all). */
|
|
Packit Service |
5ffa24 |
success = nm_utils_file_set_contents(new_path,
|
|
Packit Service |
5ffa24 |
(const char *) blob_data,
|
|
Packit Service |
5ffa24 |
blob_len,
|
|
Packit Service |
5ffa24 |
0600,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Bot |
c44df3 |
NULL,
|
|
Packit Service |
5ffa24 |
&local);
|
|
Packit Service |
5ffa24 |
if (success) {
|
|
Packit Service |
5ffa24 |
/* Write the path value to the keyfile.
|
|
Packit Service |
5ffa24 |
* We know, that basename(new_path) starts with a UUID, hence no conflict with "data:;base64," */
|
|
Packit Service |
5ffa24 |
nm_keyfile_plugin_kf_set_string(file,
|
|
Packit Service |
5ffa24 |
setting_name,
|
|
Packit Service |
5ffa24 |
vtable->setting_key,
|
|
Packit Service |
5ffa24 |
strrchr(new_path, '/') + 1);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
nm_log_warn(LOGD_SETTINGS,
|
|
Packit Service |
5ffa24 |
"keyfile: %s.%s: failed to write certificate to file %s: %s",
|
|
Packit Service |
5ffa24 |
setting_name,
|
|
Packit Service |
5ffa24 |
vtable->setting_key,
|
|
Packit Service |
5ffa24 |
new_path,
|
|
Packit Service |
5ffa24 |
local->message);
|
|
Packit Service |
5ffa24 |
g_error_free(local);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
g_free(new_path);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
/* scheme_func() returns UNKNOWN in all other cases. The only valid case
|
|
Packit Service |
5ffa24 |
* where a scheme is allowed to be UNKNOWN, is unsetting the value. In this
|
|
Packit Service |
5ffa24 |
* case, we don't expect the writer to be called, because the default value
|
|
Packit Service |
5ffa24 |
* will not be serialized.
|
|
Packit Service |
5ffa24 |
* The only other reason for the scheme to be UNKNOWN is an invalid cert.
|
|
Packit Service |
5ffa24 |
* But our connection verifies, so that cannot happen either. */
|
|
Packit Service |
5ffa24 |
g_return_if_reached();
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static gboolean
|
|
Packit Service |
5ffa24 |
_handler_write(NMConnection * connection,
|
|
Packit Service |
5ffa24 |
GKeyFile * keyfile,
|
|
Packit Service |
5ffa24 |
NMKeyfileHandlerType type,
|
|
Packit Service |
5ffa24 |
NMKeyfileHandlerData *type_data,
|
|
Packit Service |
5ffa24 |
void * user_data)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
if (type == NM_KEYFILE_HANDLER_TYPE_WRITE_CERT) {
|
|
Packit Service |
5ffa24 |
cert_writer(connection,
|
|
Packit Service |
5ffa24 |
keyfile,
|
|
Packit Service |
5ffa24 |
NM_SETTING_802_1X(type_data->cur_setting),
|
|
Packit Service |
5ffa24 |
type_data->write_cert.vtable,
|
|
Packit Service |
5ffa24 |
user_data,
|
|
Packit Service |
5ffa24 |
type_data->p_error);
|
|
Packit Service |
5ffa24 |
return TRUE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static gboolean
|
|
Packit Service |
5ffa24 |
_internal_write_connection(NMConnection * connection,
|
|
Packit Service |
5ffa24 |
gboolean is_nm_generated,
|
|
Packit Service |
5ffa24 |
gboolean is_volatile,
|
|
Packit Service |
5ffa24 |
gboolean is_external,
|
|
Packit Service |
5ffa24 |
const char * shadowed_storage,
|
|
Packit Service |
5ffa24 |
gboolean shadowed_owned,
|
|
Packit Service |
5ffa24 |
const char * keyfile_dir,
|
|
Packit Service |
5ffa24 |
const char * profile_dir,
|
|
Packit Service |
5ffa24 |
gboolean with_extension,
|
|
Packit Service |
5ffa24 |
uid_t owner_uid,
|
|
Packit Service |
5ffa24 |
pid_t owner_grp,
|
|
Packit Service |
5ffa24 |
const char * existing_path,
|
|
Packit Service |
5ffa24 |
gboolean existing_path_read_only,
|
|
Packit Service |
5ffa24 |
gboolean force_rename,
|
|
Packit Service |
5ffa24 |
NMSKeyfileWriterAllowFilenameCb allow_filename_cb,
|
|
Packit Service |
5ffa24 |
gpointer allow_filename_user_data,
|
|
Packit Service |
5ffa24 |
char ** out_path,
|
|
Packit Service |
5ffa24 |
NMConnection ** out_reread,
|
|
Packit Service |
5ffa24 |
gboolean * out_reread_same,
|
|
Packit Service |
5ffa24 |
GError ** error)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
nm_auto_unref_keyfile GKeyFile *kf_file = NULL;
|
|
Packit Service |
5ffa24 |
gs_free char * kf_content_buf = NULL;
|
|
Packit Service |
5ffa24 |
gsize kf_content_len;
|
|
Packit Service |
5ffa24 |
gs_free char * path = NULL;
|
|
Packit Service |
5ffa24 |
const char * id;
|
|
Packit Service |
5ffa24 |
WriteInfo info = {0};
|
|
Packit Service |
5ffa24 |
gs_free_error GError *local_err = NULL;
|
|
Packit Service |
5ffa24 |
int errsv;
|
|
Packit Service |
5ffa24 |
gboolean rename;
|
|
Packit Service |
5ffa24 |
int i_path;
|
|
Packit Service |
5ffa24 |
gs_unref_object NMConnection *reread = NULL;
|
|
Packit Service |
5ffa24 |
gboolean reread_same = FALSE;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_return_val_if_fail(!out_path || !*out_path, FALSE);
|
|
Packit Service |
5ffa24 |
g_return_val_if_fail(keyfile_dir && keyfile_dir[0] == '/', FALSE);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_assert(_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_assert(!shadowed_owned || shadowed_storage);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
rename = force_rename || existing_path_read_only
|
|
Packit Service |
5ffa24 |
|| (existing_path && !nm_utils_file_is_in_path(existing_path, keyfile_dir));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
id = nm_connection_get_id(connection);
|
|
Packit Service |
5ffa24 |
nm_assert(id && *id);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
info.keyfile_dir = keyfile_dir;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
kf_file =
|
|
Packit Service |
5ffa24 |
nm_keyfile_write(connection, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_write, &info, error);
|
|
Packit Service |
5ffa24 |
if (!kf_file)
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (is_nm_generated) {
|
|
Packit Service |
5ffa24 |
g_key_file_set_boolean(kf_file,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_GROUP_NMMETA,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_KEY_NMMETA_NM_GENERATED,
|
|
Packit Service |
5ffa24 |
TRUE);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (is_volatile) {
|
|
Packit Service |
5ffa24 |
g_key_file_set_boolean(kf_file,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_GROUP_NMMETA,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_KEY_NMMETA_VOLATILE,
|
|
Packit Service |
5ffa24 |
TRUE);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (is_external) {
|
|
Packit Service |
5ffa24 |
g_key_file_set_boolean(kf_file,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_GROUP_NMMETA,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_KEY_NMMETA_EXTERNAL,
|
|
Packit Service |
5ffa24 |
TRUE);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (shadowed_storage) {
|
|
Packit Service |
5ffa24 |
g_key_file_set_string(kf_file,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_GROUP_NMMETA,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE,
|
|
Packit Service |
5ffa24 |
shadowed_storage);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (shadowed_owned) {
|
|
Packit Service |
5ffa24 |
g_key_file_set_boolean(kf_file,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_GROUP_NMMETA,
|
|
Packit Service |
5ffa24 |
NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED,
|
|
Packit Service |
5ffa24 |
TRUE);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
kf_content_buf = g_key_file_to_data(kf_file, &kf_content_len, error);
|
|
Packit Service |
5ffa24 |
if (!kf_content_buf)
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!g_file_test(keyfile_dir, G_FILE_TEST_IS_DIR))
|
|
Packit Service |
5ffa24 |
(void) g_mkdir_with_parents(keyfile_dir, 0755);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
for (i_path = -2; i_path < 10000; i_path++) {
|
|
Packit Service |
5ffa24 |
gs_free char *path_candidate = NULL;
|
|
Packit Service |
5ffa24 |
gboolean is_existing_path;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (i_path == -2) {
|
|
Packit Service |
5ffa24 |
if (!existing_path || rename)
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
path_candidate = g_strdup(existing_path);
|
|
Packit Service |
5ffa24 |
} else if (i_path == -1) {
|
|
Packit Service |
5ffa24 |
gs_free char *filename_escaped = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
filename_escaped = nm_keyfile_utils_create_filename(id, with_extension);
|
|
Packit Service |
5ffa24 |
path_candidate = g_build_filename(keyfile_dir, filename_escaped, NULL);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
gs_free char *filename_escaped = NULL;
|
|
Packit Service |
5ffa24 |
gs_free char *filename = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (i_path == 0)
|
|
Packit Service |
5ffa24 |
filename = g_strdup_printf("%s-%s", id, nm_connection_get_uuid(connection));
|
|
Packit Service |
5ffa24 |
else
|
|
Packit Service |
5ffa24 |
filename =
|
|
Packit Service |
5ffa24 |
g_strdup_printf("%s-%s-%d", id, nm_connection_get_uuid(connection), i_path);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
filename_escaped = nm_keyfile_utils_create_filename(filename, with_extension);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
path_candidate = g_strdup_printf("%s/%s", keyfile_dir, filename_escaped);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
is_existing_path = existing_path && nm_streq(existing_path, path_candidate);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (is_existing_path && rename)
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (allow_filename_cb && !allow_filename_cb(path_candidate, allow_filename_user_data))
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!is_existing_path) {
|
|
Packit Service |
5ffa24 |
if (g_file_test(path_candidate, G_FILE_TEST_EXISTS))
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
path = g_steal_pointer(&path_candidate);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!path) {
|
|
Packit Service |
5ffa24 |
gs_free char *ss = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* this really should not happen, we tried hard to find an unused name... bail out. */
|
|
Packit Service |
5ffa24 |
g_set_error(error,
|
|
Packit Service |
5ffa24 |
NM_SETTINGS_ERROR,
|
|
Packit Service |
5ffa24 |
NM_SETTINGS_ERROR_FAILED,
|
|
Packit Service |
5ffa24 |
"could not find suitable keyfile file name (%s already used)",
|
|
Packit Service |
5ffa24 |
ss = ({
|
|
Packit Service |
5ffa24 |
gs_free char *filename_escaped = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
filename_escaped = nm_keyfile_utils_create_filename(id, with_extension);
|
|
Packit Service |
5ffa24 |
g_build_filename(keyfile_dir, filename_escaped, NULL);
|
|
Packit Service |
5ffa24 |
}));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (out_reread || out_reread_same) {
|
|
Packit Service |
5ffa24 |
gs_free_error GError *reread_error = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
reread =
|
|
Packit Service |
5ffa24 |
nms_keyfile_reader_from_keyfile(kf_file, path, NULL, profile_dir, FALSE, &reread_error);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!reread || !nm_connection_normalize(reread, NULL, NULL, &reread_error)) {
|
|
Packit Service |
5ffa24 |
nm_log_err(
|
|
Packit Service |
5ffa24 |
LOGD_SETTINGS,
|
|
Packit Service |
5ffa24 |
"BUG: the profile cannot be stored in keyfile format without becoming unusable: %s",
|
|
Packit Service |
5ffa24 |
reread_error->message);
|
|
Packit Service |
5ffa24 |
g_set_error(error,
|
|
Packit Service |
5ffa24 |
NM_SETTINGS_ERROR,
|
|
Packit Service |
5ffa24 |
NM_SETTINGS_ERROR_FAILED,
|
|
Packit Service |
5ffa24 |
"keyfile writer produces an invalid connection: %s",
|
|
Packit Service |
5ffa24 |
reread_error->message);
|
|
Packit Service |
5ffa24 |
nm_assert_not_reached();
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (out_reread_same) {
|
|
Packit Service |
5ffa24 |
reread_same =
|
|
Packit Service |
5ffa24 |
!!nm_connection_compare(reread, connection, NM_SETTING_COMPARE_FLAG_EXACT);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_assert(reread_same
|
|
Packit Service |
5ffa24 |
== nm_connection_compare(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
|
|
Packit Service |
5ffa24 |
nm_assert(reread_same == ({
|
|
Packit Service |
5ffa24 |
gs_unref_hashtable GHashTable *_settings = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
(nm_connection_diff(reread,
|
|
Packit Service |
5ffa24 |
connection,
|
|
Packit Service |
5ffa24 |
NM_SETTING_COMPARE_FLAG_EXACT,
|
|
Packit Service |
5ffa24 |
&_settings)
|
|
Packit Service |
5ffa24 |
&& !_settings);
|
|
Packit Service |
5ffa24 |
}));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Bot |
c44df3 |
nm_utils_file_set_contents(path, kf_content_buf, kf_content_len, 0600, NULL, NULL, &local_err);
|
|
Packit Service |
5ffa24 |
if (local_err) {
|
|
Packit Service |
5ffa24 |
g_set_error(error,
|
|
Packit Service |
5ffa24 |
NM_SETTINGS_ERROR,
|
|
Packit Service |
5ffa24 |
NM_SETTINGS_ERROR_FAILED,
|
|
Packit Service |
5ffa24 |
"error writing to file '%s': %s",
|
|
Packit Service |
5ffa24 |
path,
|
|
Packit Service |
5ffa24 |
local_err->message);
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (chown(path, owner_uid, owner_grp) < 0) {
|
|
Packit Service |
5ffa24 |
errsv = errno;
|
|
Packit Service |
5ffa24 |
g_set_error(error,
|
|
Packit Service |
5ffa24 |
NM_SETTINGS_ERROR,
|
|
Packit Service |
5ffa24 |
NM_SETTINGS_ERROR_FAILED,
|
|
Packit Service |
5ffa24 |
"error chowning '%s': %s (%d)",
|
|
Packit Service |
5ffa24 |
path,
|
|
Packit Service |
5ffa24 |
nm_strerror_native(errsv),
|
|
Packit Service |
5ffa24 |
errsv);
|
|
Packit Service |
5ffa24 |
unlink(path);
|
|
Packit Service |
5ffa24 |
return FALSE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* In case of updating the connection and changing the file path,
|
|
Packit Service |
5ffa24 |
* we need to remove the old one, not to end up with two connections.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
if (existing_path && !existing_path_read_only && !nm_streq(path, existing_path))
|
|
Packit Service |
5ffa24 |
unlink(existing_path);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
NM_SET_OUT(out_reread, g_steal_pointer(&reread));
|
|
Packit Service |
5ffa24 |
NM_SET_OUT(out_reread_same, reread_same);
|
|
Packit Service |
5ffa24 |
NM_SET_OUT(out_path, g_steal_pointer(&path));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return TRUE;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
gboolean
|
|
Packit Service |
5ffa24 |
nms_keyfile_writer_connection(NMConnection * connection,
|
|
Packit Service |
5ffa24 |
gboolean is_nm_generated,
|
|
Packit Service |
5ffa24 |
gboolean is_volatile,
|
|
Packit Service |
5ffa24 |
gboolean is_external,
|
|
Packit Service |
5ffa24 |
const char * shadowed_storage,
|
|
Packit Service |
5ffa24 |
gboolean shadowed_owned,
|
|
Packit Service |
5ffa24 |
const char * keyfile_dir,
|
|
Packit Service |
5ffa24 |
const char * profile_dir,
|
|
Packit Service |
5ffa24 |
const char * existing_path,
|
|
Packit Service |
5ffa24 |
gboolean existing_path_read_only,
|
|
Packit Service |
5ffa24 |
gboolean force_rename,
|
|
Packit Service |
5ffa24 |
NMSKeyfileWriterAllowFilenameCb allow_filename_cb,
|
|
Packit Service |
5ffa24 |
gpointer allow_filename_user_data,
|
|
Packit Service |
5ffa24 |
char ** out_path,
|
|
Packit Service |
5ffa24 |
NMConnection ** out_reread,
|
|
Packit Service |
5ffa24 |
gboolean * out_reread_same,
|
|
Packit Service |
5ffa24 |
GError ** error)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
return _internal_write_connection(connection,
|
|
Packit Service |
5ffa24 |
is_nm_generated,
|
|
Packit Service |
5ffa24 |
is_volatile,
|
|
Packit Service |
5ffa24 |
is_external,
|
|
Packit Service |
5ffa24 |
shadowed_storage,
|
|
Packit Service |
5ffa24 |
shadowed_owned,
|
|
Packit Service |
5ffa24 |
keyfile_dir,
|
|
Packit Service |
5ffa24 |
profile_dir,
|
|
Packit Service |
5ffa24 |
TRUE,
|
|
Packit Service |
5ffa24 |
0,
|
|
Packit Service |
5ffa24 |
0,
|
|
Packit Service |
5ffa24 |
existing_path,
|
|
Packit Service |
5ffa24 |
existing_path_read_only,
|
|
Packit Service |
5ffa24 |
force_rename,
|
|
Packit Service |
5ffa24 |
allow_filename_cb,
|
|
Packit Service |
5ffa24 |
allow_filename_user_data,
|
|
Packit Service |
5ffa24 |
out_path,
|
|
Packit Service |
5ffa24 |
out_reread,
|
|
Packit Service |
5ffa24 |
out_reread_same,
|
|
Packit Service |
5ffa24 |
error);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
gboolean
|
|
Packit Service |
5ffa24 |
nms_keyfile_writer_test_connection(NMConnection * connection,
|
|
Packit Service |
5ffa24 |
const char * keyfile_dir,
|
|
Packit Service |
5ffa24 |
uid_t owner_uid,
|
|
Packit Service |
5ffa24 |
pid_t owner_grp,
|
|
Packit Service |
5ffa24 |
char ** out_path,
|
|
Packit Service |
5ffa24 |
NMConnection **out_reread,
|
|
Packit Service |
5ffa24 |
gboolean * out_reread_same,
|
|
Packit Service |
5ffa24 |
GError ** error)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
return _internal_write_connection(connection,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
keyfile_dir,
|
|
Packit Service |
5ffa24 |
keyfile_dir,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
owner_uid,
|
|
Packit Service |
5ffa24 |
owner_grp,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
out_path,
|
|
Packit Service |
5ffa24 |
out_reread,
|
|
Packit Service |
5ffa24 |
out_reread_same,
|
|
Packit Service |
5ffa24 |
error);
|
|
Packit Service |
5ffa24 |
}
|