diff options
Diffstat (limited to 'shared/nm-libnm-core-intern')
| -rw-r--r-- | shared/nm-libnm-core-intern/nm-auth-subject.c | 446 | ||||
| -rw-r--r-- | shared/nm-libnm-core-intern/nm-auth-subject.h | 56 | ||||
| -rw-r--r-- | shared/nm-libnm-core-intern/nm-ethtool-utils.h | 2 | ||||
| -rw-r--r-- | shared/nm-libnm-core-intern/nm-libnm-core-utils.c | 119 | ||||
| -rw-r--r-- | shared/nm-libnm-core-intern/nm-libnm-core-utils.h | 13 |
5 files changed, 635 insertions, 1 deletions
diff --git a/shared/nm-libnm-core-intern/nm-auth-subject.c b/shared/nm-libnm-core-intern/nm-auth-subject.c new file mode 100644 index 00000000..15c2d652 --- /dev/null +++ b/shared/nm-libnm-core-intern/nm-auth-subject.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: LGPL-2.1+ +/* + * Copyright (C) 2013 - 2014 Red Hat, Inc. + */ + +/** + * SECTION:nm-auth-subject + * @short_description: Encapsulates authentication information about a requestor + * + * #NMAuthSubject encpasulates identifying information about an entity that + * makes requests, like process identifier and user UID. + */ + +#include "nm-default.h" + +#include "nm-auth-subject.h" + +#include <stdlib.h> + +enum { + PROP_0, + PROP_SUBJECT_TYPE, + PROP_UNIX_PROCESS_DBUS_SENDER, + PROP_UNIX_PROCESS_PID, + PROP_UNIX_PROCESS_UID, + PROP_UNIX_SESSION_ID, + + PROP_LAST, +}; + +typedef struct { + NMAuthSubjectType subject_type; + struct { + gulong pid; + gulong uid; + guint64 start_time; + char *dbus_sender; + } unix_process; + + struct { + char *id; + } unix_session; +} NMAuthSubjectPrivate; + +struct _NMAuthSubject { + GObject parent; + NMAuthSubjectPrivate _priv; +}; + +struct _NMAuthSubjectClass { + GObjectClass parent; +}; + +G_DEFINE_TYPE (NMAuthSubject, nm_auth_subject, G_TYPE_OBJECT) + +#define NM_AUTH_SUBJECT_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMAuthSubject, NM_IS_AUTH_SUBJECT) + +/*****************************************************************************/ + +#define CHECK_SUBJECT(self, error_value) \ + NMAuthSubjectPrivate *priv; \ + g_return_val_if_fail (NM_IS_AUTH_SUBJECT (self), error_value); \ + priv = NM_AUTH_SUBJECT_GET_PRIVATE (self); \ + +#define CHECK_SUBJECT_TYPED(self, expected_subject_type, error_value) \ + CHECK_SUBJECT (self, error_value); \ + g_return_val_if_fail (priv->subject_type == (expected_subject_type), error_value); + +const char * +nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len) +{ + CHECK_SUBJECT (self, NULL); + + switch (priv->subject_type) { + case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: + g_snprintf (buf, buf_len, "unix-process[pid=%lu, uid=%lu, start=%llu]", + (unsigned long) priv->unix_process.pid, + (unsigned long) priv->unix_process.uid, + (unsigned long long) priv->unix_process.start_time); + break; + case NM_AUTH_SUBJECT_TYPE_INTERNAL: + g_strlcpy (buf, "internal", buf_len); + break; + case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION: + g_snprintf (buf, buf_len, "unix-session[id=%s]", + priv->unix_session.id); + break; + default: + g_strlcpy (buf, "invalid", buf_len); + break; + } + return buf; +} + +/* returns a floating variant */ +GVariant * +nm_auth_subject_unix_to_polkit_gvariant (NMAuthSubject *self) +{ + GVariantBuilder builder; + CHECK_SUBJECT (self, NULL); + + switch (priv->subject_type) { + + case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION: + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", "session-id", + g_variant_new_string (priv->unix_session.id)); + return g_variant_new ("(sa{sv})", "unix-session", &builder); + + case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", "pid", + g_variant_new_uint32 (priv->unix_process.pid)); + g_variant_builder_add (&builder, "{sv}", "start-time", + g_variant_new_uint64 (priv->unix_process.start_time)); + g_variant_builder_add (&builder, "{sv}", "uid", + g_variant_new_int32 (priv->unix_process.uid)); + return g_variant_new ("(sa{sv})", "unix-process", &builder); + + default: + g_return_val_if_reached (NULL); + } +} + +NMAuthSubjectType +nm_auth_subject_get_subject_type (NMAuthSubject *subject) +{ + CHECK_SUBJECT (subject, NM_AUTH_SUBJECT_TYPE_INVALID); + + return priv->subject_type; +} + +gulong +nm_auth_subject_get_unix_process_pid (NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED (subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, G_MAXULONG); + + return priv->unix_process.pid; +} + +gulong +nm_auth_subject_get_unix_process_uid (NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED (subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, G_MAXULONG); + + return priv->unix_process.uid; +} + +const char * +nm_auth_subject_get_unix_process_dbus_sender (NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED (subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL); + + return priv->unix_process.dbus_sender; +} + +const char * +nm_auth_subject_get_unix_session_id (NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED (subject, NM_AUTH_SUBJECT_TYPE_UNIX_SESSION, NULL); + + return priv->unix_session.id; +} + +/*****************************************************************************/ + +/** + * nm_auth_subject_new_internal(): + * + * Creates a new auth subject representing the NetworkManager process itself. + * + * Returns: the new #NMAuthSubject + */ +NMAuthSubject * +nm_auth_subject_new_internal (void) +{ + return NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT, + NM_AUTH_SUBJECT_SUBJECT_TYPE, (int) NM_AUTH_SUBJECT_TYPE_INTERNAL, + NULL)); +} + +/** + * nm_auth_subject_new_unix_session(): + * + * Creates a new auth subject representing a given unix session. + * + * Returns: the new #NMAuthSubject + */ +NMAuthSubject * +nm_auth_subject_new_unix_session (const char *session_id) +{ + return NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT, + NM_AUTH_SUBJECT_SUBJECT_TYPE, (int) NM_AUTH_SUBJECT_TYPE_UNIX_SESSION, + NM_AUTH_SUBJECT_UNIX_SESSION_ID, session_id, + NULL)); +} + +/** + * nm_auth_subject_new_unix_process(): + * + * Creates a new auth subject representing a given unix process. + * + * Returns: the new #NMAuthSubject + */ +NMAuthSubject * +nm_auth_subject_new_unix_process (const char *dbus_sender, gulong pid, gulong uid) +{ + return NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT, + NM_AUTH_SUBJECT_SUBJECT_TYPE, (int) NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, + NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER, dbus_sender, + NM_AUTH_SUBJECT_UNIX_PROCESS_PID, pid, + NM_AUTH_SUBJECT_UNIX_PROCESS_UID, uid, + NULL)); +} + +/** + * nm_auth_subject_new_unix_process_self(): + * + * Creates a new auth subject representing the current executing process. + * + * Returns: the new #NMAuthSubject + */ +NMAuthSubject * +nm_auth_subject_new_unix_process_self (void) +{ + return nm_auth_subject_new_unix_process (NULL, getpid(), getuid()); +} + +/*****************************************************************************/ + +static void +get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SUBJECT_TYPE: + g_value_set_int (value, priv->subject_type); + break; + case PROP_UNIX_PROCESS_DBUS_SENDER: + g_value_set_string (value, priv->unix_process.dbus_sender); + break; + case PROP_UNIX_PROCESS_PID: + g_value_set_ulong (value, priv->unix_process.pid); + break; + case PROP_UNIX_PROCESS_UID: + g_value_set_ulong (value, priv->unix_process.uid); + break; + case PROP_UNIX_SESSION_ID: + g_value_set_string (value, priv->unix_session.id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object); + NMAuthSubjectType subject_type; + int i; + const char *str; + gulong id; + + switch (prop_id) { + case PROP_SUBJECT_TYPE: + /* construct-only */ + i = g_value_get_int (value); + g_return_if_fail (NM_IN_SET (i, + (int) NM_AUTH_SUBJECT_TYPE_INTERNAL, + (int) NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, + (int) NM_AUTH_SUBJECT_TYPE_UNIX_SESSION)); + subject_type = i; + priv->subject_type |= subject_type; + g_return_if_fail (priv->subject_type == subject_type); + break; + case PROP_UNIX_PROCESS_DBUS_SENDER: + /* construct-only */ + if ((str = g_value_get_string (value))) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail (priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.dbus_sender = g_strdup (str); + } + break; + case PROP_UNIX_PROCESS_PID: + /* construct-only */ + if ((id = g_value_get_ulong (value)) != G_MAXULONG) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail (priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.pid = id; + } + break; + case PROP_UNIX_PROCESS_UID: + /* construct-only */ + if ((id = g_value_get_ulong (value)) != G_MAXULONG) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail (priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.uid = id; + } + break; + case PROP_UNIX_SESSION_ID: + /* construct-only */ + if ((str = g_value_get_string (value))) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_SESSION; + g_return_if_fail (priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_SESSION); + priv->unix_session.id = g_strdup (str); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +_clear_private (NMAuthSubject *self) +{ + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (self); + + priv->subject_type = NM_AUTH_SUBJECT_TYPE_INVALID; + priv->unix_process.pid = G_MAXULONG; + priv->unix_process.uid = G_MAXULONG; + nm_clear_g_free (&priv->unix_process.dbus_sender); + + nm_clear_g_free (&priv->unix_session.id); +} + +static void +nm_auth_subject_init (NMAuthSubject *self) +{ + _clear_private (self); +} + +static void +constructed (GObject *object) +{ + NMAuthSubject *self = NM_AUTH_SUBJECT (object); + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (self); + + /* validate that the created instance. */ + + switch (priv->subject_type) { + case NM_AUTH_SUBJECT_TYPE_INTERNAL: + priv->unix_process.pid = G_MAXULONG; + priv->unix_process.uid = 0; /* internal uses 'root' user */ + return; + case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: + /* Ensure pid and uid to be representable as int32. + * DBUS treats them as uint32, polkit library as int. */ + if (priv->unix_process.pid > MIN (G_MAXINT, G_MAXINT32)) + break; + if (priv->unix_process.uid > MIN (G_MAXINT, G_MAXINT32)) { + /* for uid==-1, libpolkit-gobject-1 detects the user based on the process id. + * Don't bother and require the user id as parameter. */ + break; + } + + priv->unix_process.start_time = nm_utils_get_start_time_for_pid (priv->unix_process.pid, NULL, NULL); + + if (!priv->unix_process.start_time) { + /* Is the process already gone? Then fail creation of the auth subject + * by clearing the type. */ + if (kill (priv->unix_process.pid, 0) != 0) + _clear_private (self); + + /* Otherwise, although we didn't detect a start_time, the process is still around. + * That could be due to procfs mounted with hidepid. So just accept the request. + * + * Polkit on the other side, will accept 0 and try to lookup /proc/$PID/stat + * itself (and if it fails to do so, assume a start-time of 0 and proceed). + * The only combination that would fail here, is when NM is able to read the + * start-time, but polkit is not. */ + } + return; + case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION: + return; + default: + break; + } + + _clear_private (self); + g_return_if_reached (); +} + +static void +finalize (GObject *object) +{ + _clear_private ((NMAuthSubject *) object); + + G_OBJECT_CLASS (nm_auth_subject_parent_class)->finalize (object); +} + +static void +nm_auth_subject_class_init (NMAuthSubjectClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->finalize = finalize; + + g_object_class_install_property + (object_class, PROP_SUBJECT_TYPE, + g_param_spec_int (NM_AUTH_SUBJECT_SUBJECT_TYPE, "", "", + NM_AUTH_SUBJECT_TYPE_INVALID, + NM_AUTH_SUBJECT_TYPE_UNIX_SESSION, + NM_AUTH_SUBJECT_TYPE_INVALID, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_UNIX_PROCESS_DBUS_SENDER, + g_param_spec_string (NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_UNIX_PROCESS_PID, + g_param_spec_ulong (NM_AUTH_SUBJECT_UNIX_PROCESS_PID, "", "", + 0, G_MAXULONG, G_MAXULONG, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_UNIX_PROCESS_UID, + g_param_spec_ulong (NM_AUTH_SUBJECT_UNIX_PROCESS_UID, "", "", + 0, G_MAXULONG, G_MAXULONG, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_UNIX_SESSION_ID, + g_param_spec_string (NM_AUTH_SUBJECT_UNIX_SESSION_ID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} diff --git a/shared/nm-libnm-core-intern/nm-auth-subject.h b/shared/nm-libnm-core-intern/nm-auth-subject.h new file mode 100644 index 00000000..fc37b8e2 --- /dev/null +++ b/shared/nm-libnm-core-intern/nm-auth-subject.h @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: LGPL-2.1+ +/* + * Copyright (C) 2013 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_AUTH_SUBJECT_H__ +#define __NETWORKMANAGER_AUTH_SUBJECT_H__ + +#define NM_TYPE_AUTH_SUBJECT (nm_auth_subject_get_type ()) +#define NM_AUTH_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AUTH_SUBJECT, NMAuthSubject)) +#define NM_AUTH_SUBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectClass)) +#define NM_IS_AUTH_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_AUTH_SUBJECT)) +#define NM_IS_AUTH_SUBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_AUTH_SUBJECT)) +#define NM_AUTH_SUBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectClass)) + +typedef enum { + NM_AUTH_SUBJECT_TYPE_INVALID = 0, + NM_AUTH_SUBJECT_TYPE_INTERNAL = 1, + NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS = 2, + NM_AUTH_SUBJECT_TYPE_UNIX_SESSION = 4, +} NMAuthSubjectType; + +#define NM_AUTH_SUBJECT_SUBJECT_TYPE "subject-type" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER "unix-process-dbus-sender" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_PID "unix-process-pid" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_UID "unix-process-uid" +#define NM_AUTH_SUBJECT_UNIX_SESSION_ID "unix-session-id" + +typedef struct _NMAuthSubjectClass NMAuthSubjectClass; +typedef struct _NMAuthSubject NMAuthSubject; + +GType nm_auth_subject_get_type (void); + +NMAuthSubject *nm_auth_subject_new_internal (void); + +NMAuthSubject *nm_auth_subject_new_unix_session (const char *session_id); + +NMAuthSubject *nm_auth_subject_new_unix_process (const char *dbus_sender, gulong pid, gulong uid); + +NMAuthSubject *nm_auth_subject_new_unix_process_self (void); + +NMAuthSubjectType nm_auth_subject_get_subject_type (NMAuthSubject *subject); + +gulong nm_auth_subject_get_unix_process_pid (NMAuthSubject *subject); + +const char *nm_auth_subject_get_unix_process_dbus_sender (NMAuthSubject *subject); + +gulong nm_auth_subject_get_unix_process_uid (NMAuthSubject *subject); + +const char *nm_auth_subject_get_unix_session_id (NMAuthSubject *subject); + +const char *nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len); + +GVariant *nm_auth_subject_unix_to_polkit_gvariant (NMAuthSubject *self); + +#endif /* __NETWORKMANAGER_AUTH_SUBJECT_H__ */ diff --git a/shared/nm-libnm-core-intern/nm-ethtool-utils.h b/shared/nm-libnm-core-intern/nm-ethtool-utils.h index 463d8e8f..b3413de2 100644 --- a/shared/nm-libnm-core-intern/nm-ethtool-utils.h +++ b/shared/nm-libnm-core-intern/nm-ethtool-utils.h @@ -79,7 +79,7 @@ typedef struct { NMEthtoolID id; } NMEthtoolData; -extern const NMEthtoolData *const nm_ethtool_data[/*_NM_ETHTOOL_ID_NUM + NULL-terminated*/]; +extern const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1]; const NMEthtoolData *nm_ethtool_data_get_by_optname (const char *optname); diff --git a/shared/nm-libnm-core-intern/nm-libnm-core-utils.c b/shared/nm-libnm-core-intern/nm-libnm-core-utils.c index 9bf0b120..df2f2e77 100644 --- a/shared/nm-libnm-core-intern/nm-libnm-core-utils.c +++ b/shared/nm-libnm-core-intern/nm-libnm-core-utils.c @@ -4,6 +4,8 @@ #include "nm-libnm-core-utils.h" +#include "nm-common-macros.h" + /*****************************************************************************/ gboolean @@ -59,3 +61,120 @@ nm_utils_vlan_priority_map_parse_str (NMVlanPriorityMap map_type, NM_SET_OUT (out_has_wildcard_to, v2 < 0); return TRUE; } + +/*****************************************************************************/ + +const char *const nm_auth_permission_names_by_idx[NM_CLIENT_PERMISSION_LAST] = { + [NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK - 1] = NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, + [NM_CLIENT_PERMISSION_NETWORK_CONTROL - 1] = NM_AUTH_PERMISSION_NETWORK_CONTROL, + [NM_CLIENT_PERMISSION_RELOAD - 1] = NM_AUTH_PERMISSION_RELOAD, + [NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, + [NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, + [NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, + [NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, + [NM_CLIENT_PERMISSION_SLEEP_WAKE - 1] = NM_AUTH_PERMISSION_SLEEP_WAKE, + [NM_CLIENT_PERMISSION_WIFI_SCAN - 1] = NM_AUTH_PERMISSION_WIFI_SCAN, + [NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN - 1] = NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, + [NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED - 1] = NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, +}; + +const NMClientPermission nm_auth_permission_sorted[NM_CLIENT_PERMISSION_LAST] = { + NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN, + NM_CLIENT_PERMISSION_NETWORK_CONTROL, + NM_CLIENT_PERMISSION_RELOAD, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM, + NM_CLIENT_PERMISSION_SLEEP_WAKE, + NM_CLIENT_PERMISSION_WIFI_SCAN, + NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN, + NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED, +}; + +const char * +nm_auth_permission_to_string (NMClientPermission permission) +{ + if (permission < 1) + return NULL; + if (permission > NM_CLIENT_PERMISSION_LAST) + return NULL; + return nm_auth_permission_names_by_idx[permission - 1]; +} + +#define AUTH_PERMISSION_PREFIX "org.freedesktop.NetworkManager." + +static int +_nm_auth_permission_from_string_cmp (gconstpointer a, gconstpointer b, gpointer user_data) +{ + const NMClientPermission *const p = a; + const char *const needle = b; + const char *ss = nm_auth_permission_names_by_idx[*p - 1]; + + nm_assert (NM_STR_HAS_PREFIX (ss, AUTH_PERMISSION_PREFIX)); + nm_assert (ss[NM_STRLEN (AUTH_PERMISSION_PREFIX)] != '\0'); + + return strcmp (&ss[NM_STRLEN (AUTH_PERMISSION_PREFIX)], needle); +} + +NMClientPermission +nm_auth_permission_from_string (const char *str) +{ + gssize idx; + + if (!str) + return NM_CLIENT_PERMISSION_NONE; + + if (!NM_STR_HAS_PREFIX (str, AUTH_PERMISSION_PREFIX)) + return NM_CLIENT_PERMISSION_NONE; + idx = nm_utils_array_find_binary_search (nm_auth_permission_sorted, + sizeof (nm_auth_permission_sorted[0]), + G_N_ELEMENTS (nm_auth_permission_sorted), + &str[NM_STRLEN (AUTH_PERMISSION_PREFIX)], + _nm_auth_permission_from_string_cmp, + NULL); + if (idx < 0) + return NM_CLIENT_PERMISSION_NONE; + return nm_auth_permission_sorted[idx]; +} + +/*****************************************************************************/ + +NMClientPermissionResult +nm_client_permission_result_from_string (const char *nm) +{ + if (!nm) + return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + if (nm_streq (nm, "yes")) + return NM_CLIENT_PERMISSION_RESULT_YES; + if (nm_streq (nm, "no")) + return NM_CLIENT_PERMISSION_RESULT_NO; + if (nm_streq (nm, "auth")) + return NM_CLIENT_PERMISSION_RESULT_AUTH; + return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; +} + +const char * +nm_client_permission_result_to_string (NMClientPermissionResult permission) +{ + switch (permission) { + case NM_CLIENT_PERMISSION_RESULT_YES: return "yes"; + case NM_CLIENT_PERMISSION_RESULT_NO: return "no"; + case NM_CLIENT_PERMISSION_RESULT_AUTH: return "auth"; + case NM_CLIENT_PERMISSION_RESULT_UNKNOWN: return "unknown"; + } + nm_assert_not_reached (); + return NULL; +} diff --git a/shared/nm-libnm-core-intern/nm-libnm-core-utils.h b/shared/nm-libnm-core-intern/nm-libnm-core-utils.h index 1449a8ba..a35a5e15 100644 --- a/shared/nm-libnm-core-intern/nm-libnm-core-utils.h +++ b/shared/nm-libnm-core-intern/nm-libnm-core-utils.h @@ -99,4 +99,17 @@ nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip) #define _NM_CAPABILITY_MAX NM_CAPABILITY_OVS +/*****************************************************************************/ + +extern const char *const nm_auth_permission_names_by_idx[NM_CLIENT_PERMISSION_LAST]; +extern const NMClientPermission nm_auth_permission_sorted[NM_CLIENT_PERMISSION_LAST]; + +const char *nm_auth_permission_to_string (NMClientPermission permission); +NMClientPermission nm_auth_permission_from_string (const char *str); + +/*****************************************************************************/ + +NMClientPermissionResult nm_client_permission_result_from_string (const char *nm); +const char *nm_client_permission_result_to_string (NMClientPermissionResult permission); + #endif /* __NM_LIBNM_SHARED_UTILS_H__ */ |