diff --git a/src/core/main-utils.c b/src/core/main-utils.c index 7fcffcbc08..444e122e8a 100644 --- a/src/core/main-utils.c +++ b/src/core/main-utils.c @@ -209,15 +209,6 @@ nm_main_utils_ensure_not_running_pidfile(const char *pidfile) } } -void -nm_main_utils_ensure_root() -{ - if (getuid() != 0) { - fprintf(stderr, _("You must be root to run %s!\n"), g_get_prgname() ?: ""); - exit(1); - } -} - gboolean nm_main_utils_early_setup(const char *progname, int *argc, diff --git a/src/core/main-utils.h b/src/core/main-utils.h index e3a3b490a9..1c3e7a1cbe 100644 --- a/src/core/main-utils.h +++ b/src/core/main-utils.h @@ -6,8 +6,6 @@ #ifndef __MAIN_UTILS_H__ #define __MAIN_UTILS_H__ -void nm_main_utils_ensure_root(void); - void nm_main_utils_setup_signals(GMainLoop *main_loop); void nm_main_utils_ensure_statedir(void); diff --git a/src/core/main.c b/src/core/main.c index 50f70a9923..e39a961416 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -328,8 +328,6 @@ main(int argc, char *argv[]) exit(result); } - nm_main_utils_ensure_root(); - nm_main_utils_ensure_not_running_pidfile(global_opt.pidfile); nm_main_utils_ensure_statedir(); diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 908cfd8912..e05638e43c 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -5145,3 +5145,59 @@ nm_utils_spawn_helper_finish(GAsyncResult *result, GError **error) return g_task_propagate_pointer(task, error); } + +/*****************************************************************************/ + +/** + * nm_utils_get_nm_uid: + * + * Checks what EUID NetworkManager is running as. + * Saves the EUID so it can be reused without making many syscalls. + */ +uid_t +nm_utils_get_nm_uid(void) +{ + static int u_static = -1; + int u; + +again: + if ((u = g_atomic_int_get(&u_static)) == -1) { + uid_t u2; + + u2 = geteuid(); + u = u2; + nm_assert(u == u2); + nm_assert(u >= 0); + if (!g_atomic_int_compare_and_exchange(&u_static, -1, u)) + goto again; + } + + return u; +} + +/** + * nm_utils_get_nm_gid: + * + * Checks what EGID NetworkManager is running as. + * Saves the EGID so it can be reused without making many syscalls. + */ +gid_t +nm_utils_get_nm_gid(void) +{ + static int g_static = -1; + int g; + +again: + if ((g = g_atomic_int_get(&g_static)) == -1) { + gid_t g2; + + g2 = geteuid(); + g = g2; + nm_assert(g == g2); + nm_assert(g >= 0); + if (!g_atomic_int_compare_and_exchange(&g_static, -1, g)) + goto again; + } + + return g; +} diff --git a/src/core/nm-core-utils.h b/src/core/nm-core-utils.h index c3ce85fa04..7079ab2f25 100644 --- a/src/core/nm-core-utils.h +++ b/src/core/nm-core-utils.h @@ -9,6 +9,7 @@ #include #include +#include #include "nm-connection.h" @@ -470,4 +471,10 @@ void nm_utils_spawn_helper(const char *const *args, char *nm_utils_spawn_helper_finish(GAsyncResult *result, GError **error); +/*****************************************************************************/ + +uid_t nm_utils_get_nm_uid(void); + +gid_t nm_utils_get_nm_gid(void); + #endif /* __NM_CORE_UTILS_H__ */ diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-utils.c b/src/core/settings/plugins/keyfile/nms-keyfile-utils.c index 68ceee5d26..7c0e329e2d 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-utils.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-utils.c @@ -337,7 +337,7 @@ nms_keyfile_utils_check_file_permissions_stat(NMSKeyfileFiletype filetype, g_return_val_if_reached(FALSE); if (!NM_FLAGS_HAS(nm_utils_get_testing(), NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK)) { - if (st->st_uid != 0) { + if (!NM_IN_SET(st->st_uid, 0, nm_utils_get_nm_uid())) { g_set_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, diff --git a/src/core/settings/plugins/keyfile/nms-keyfile-writer.c b/src/core/settings/plugins/keyfile/nms-keyfile-writer.c index 73788e891e..ad6f277ce3 100644 --- a/src/core/settings/plugins/keyfile/nms-keyfile-writer.c +++ b/src/core/settings/plugins/keyfile/nms-keyfile-writer.c @@ -444,8 +444,8 @@ nms_keyfile_writer_connection(NMConnection *connection, keyfile_dir, profile_dir, TRUE, - 0, - 0, + nm_utils_get_nm_uid(), + nm_utils_get_nm_gid(), existing_path, existing_path_read_only, force_rename,