diff options
| author | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
| commit | e74c568b07b50b97873fb4ee1d776dedefbd54d6 (patch) | |
| tree | 3469f17ea9af91f7ff169b890633bda68b0cf76e /src/libnm-core-aux-intern | |
| parent | bfe522304da217296e2a61040f58e35ec5d6f3f2 (diff) | |
New upstream version 1.32.12 upstream/1.32.12
Diffstat (limited to 'src/libnm-core-aux-intern')
| -rw-r--r-- | src/libnm-core-aux-intern/README.md | 28 | ||||
| -rw-r--r-- | src/libnm-core-aux-intern/meson.build | 13 | ||||
| -rw-r--r-- | src/libnm-core-aux-intern/nm-auth-subject.c | 468 | ||||
| -rw-r--r-- | src/libnm-core-aux-intern/nm-auth-subject.h | 59 | ||||
| -rw-r--r-- | src/libnm-core-aux-intern/nm-common-macros.h | 65 | ||||
| -rw-r--r-- | src/libnm-core-aux-intern/nm-libnm-core-utils.c | 360 | ||||
| -rw-r--r-- | src/libnm-core-aux-intern/nm-libnm-core-utils.h | 169 |
7 files changed, 1162 insertions, 0 deletions
diff --git a/src/libnm-core-aux-intern/README.md b/src/libnm-core-aux-intern/README.md new file mode 100644 index 00000000..37e238f1 --- /dev/null +++ b/src/libnm-core-aux-intern/README.md @@ -0,0 +1,28 @@ +libnm-core-aux-intern +===================== + +`libnm-core-aux-intern` is a static library that: + + - uses parts of [`libnm-core-impl`](../libnm-core-impl), that are public API + of [`libnm`](../../libnm) (i.e. [`libnm-core-public`](../libnm-core-public)). + - that is statically linked into [`libnm-core-impl`](../libnm-core-impl) (and thus + [`libnm`](../libnm) and NetworkManager core. + - that can also be statically linked into other users of [`libnm`](../libnm). + +Basically, it is a static library with utility functions that extends +[`libnm-core-impl`](../libnm-core-impl) (the part that is public API of libnm), +but it is also used by [`libnm-core-impl`](../libnm-core-impl) itself. + +That means: + + - you can use it everywhere where you either statically link + with [`libnm-core-impl`](../libnm-core-impl), or dynamically link with + [`libnm`](../../libnm). + - you can even use it inside of [`libnm-core-impl`](../libnm-core-impl) itself. + This is the difference between `libnm-core-aux-intern` and + [`libnm-core-aux-extern`](..libnm-core-aux-extern). + +Note that `libnm-core-aux-intern` only uses public API of `libnm`. + +This directory should not be added to the include search path. Instead, +users should fully qualify the include like `#include "libnm-core-aux-intern/nm-auth-subject.h"`. diff --git a/src/libnm-core-aux-intern/meson.build b/src/libnm-core-aux-intern/meson.build new file mode 100644 index 00000000..a58921e3 --- /dev/null +++ b/src/libnm-core-aux-intern/meson.build @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnm_core_aux_intern = static_library( + 'nm-core-aux-intern', + sources: files( + 'nm-auth-subject.c', + 'nm-libnm-core-utils.c', + ), + dependencies: [ + libnm_core_public_dep, + glib_dep, + ], +) diff --git a/src/libnm-core-aux-intern/nm-auth-subject.c b/src/libnm-core-aux-intern/nm-auth-subject.c new file mode 100644 index 00000000..536b4e47 --- /dev/null +++ b/src/libnm-core-aux-intern/nm-auth-subject.c @@ -0,0 +1,468 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * 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 "libnm-glib-aux/nm-default-glib-i18n-lib.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 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 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 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/src/libnm-core-aux-intern/nm-auth-subject.h b/src/libnm-core-aux-intern/nm-auth-subject.h new file mode 100644 index 00000000..2c9c4f71 --- /dev/null +++ b/src/libnm-core-aux-intern/nm-auth-subject.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * 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/src/libnm-core-aux-intern/nm-common-macros.h b/src/libnm-core-aux-intern/nm-common-macros.h new file mode 100644 index 00000000..c452b7d3 --- /dev/null +++ b/src/libnm-core-aux-intern/nm-common-macros.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2016 Red Hat, Inc. + */ + +#ifndef __NM_COMMON_MACROS_H__ +#define __NM_COMMON_MACROS_H__ + +/*****************************************************************************/ + +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK \ + "org.freedesktop.NetworkManager.enable-disable-network" +#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX \ + "org.freedesktop.NetworkManager.enable-disable-wimax" +#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" +#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED \ + "org.freedesktop.NetworkManager.wifi.share.protected" +#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM \ + "org.freedesktop.NetworkManager.settings.modify.system" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME \ + "org.freedesktop.NetworkManager.settings.modify.hostname" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS \ + "org.freedesktop.NetworkManager.settings.modify.global-dns" +#define NM_AUTH_PERMISSION_RELOAD "org.freedesktop.NetworkManager.reload" +#define NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK "org.freedesktop.NetworkManager.checkpoint-rollback" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS \ + "org.freedesktop.NetworkManager.enable-disable-statistics" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK \ + "org.freedesktop.NetworkManager.enable-disable-connectivity-check" +#define NM_AUTH_PERMISSION_WIFI_SCAN "org.freedesktop.NetworkManager.wifi.scan" + +#define NM_CLONED_MAC_PRESERVE "preserve" +#define NM_CLONED_MAC_PERMANENT "permanent" +#define NM_CLONED_MAC_RANDOM "random" +#define NM_CLONED_MAC_STABLE "stable" + +static inline gboolean +NM_CLONED_MAC_IS_SPECIAL(const char *str) +{ + return NM_IN_STRSET(str, + NM_CLONED_MAC_PRESERVE, + NM_CLONED_MAC_PERMANENT, + NM_CLONED_MAC_RANDOM, + NM_CLONED_MAC_STABLE); +} + +#define NM_IAID_MAC "mac" +#define NM_IAID_PERM_MAC "perm-mac" +#define NM_IAID_IFNAME "ifname" +#define NM_IAID_STABLE "stable" + +#define NM_CONNECTION_MUD_URL_NONE "none" + +static inline gboolean +NM_IAID_IS_SPECIAL(const char *str) +{ + return NM_IN_STRSET(str, NM_IAID_MAC, NM_IAID_PERM_MAC, NM_IAID_IFNAME, NM_IAID_STABLE); +} + +#endif /* __NM_COMMON_MACROS_H__ */ diff --git a/src/libnm-core-aux-intern/nm-libnm-core-utils.c b/src/libnm-core-aux-intern/nm-libnm-core-utils.c new file mode 100644 index 00000000..e53f840a --- /dev/null +++ b/src/libnm-core-aux-intern/nm-libnm-core-utils.c @@ -0,0 +1,360 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-glib-aux/nm-default-glib-i18n-lib.h" + +#include "nm-libnm-core-utils.h" + +#include <linux/rtnetlink.h> + +#include "nm-common-macros.h" +#include "nm-errors.h" + +/*****************************************************************************/ + +const char ** +nm_utils_bond_option_arp_ip_targets_split(const char *arp_ip_target) +{ + return nm_utils_strsplit_set_full(arp_ip_target, ",", NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); +} + +void +_nm_setting_bond_remove_options_miimon(NMSettingBond *s_bond) +{ + g_return_if_fail(NM_IS_SETTING_BOND(s_bond)); + + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_MIIMON); + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_UPDELAY); + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY); + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY); +} + +void +_nm_setting_bond_remove_options_arp_interval(NMSettingBond *s_bond) +{ + g_return_if_fail(NM_IS_SETTING_BOND(s_bond)); + + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL); + nm_setting_bond_remove_option(s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET); +} + +/*****************************************************************************/ + +NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( + _nm_setting_bond_mode_from_string, + NMBondMode, + { + G_STATIC_ASSERT_EXPR(_NM_BOND_MODE_NUM <= 9); + + if (name && name[0] < '0' + _NM_BOND_MODE_NUM && name[0] >= '0' && name[1] == '\0') { + return name[0] - '0'; + } + }, + { return NM_BOND_MODE_UNKNOWN; }, + {"802.3ad", NM_BOND_MODE_8023AD}, + {"active-backup", NM_BOND_MODE_ACTIVEBACKUP}, + {"balance-alb", NM_BOND_MODE_ALB}, + {"balance-rr", NM_BOND_MODE_ROUNDROBIN}, + {"balance-tlb", NM_BOND_MODE_TLB}, + {"balance-xor", NM_BOND_MODE_XOR}, + {"broadcast", NM_BOND_MODE_BROADCAST}, ); + +const char * +_nm_setting_bond_mode_to_string(int mode) +{ + static const char *const modes[] = { + [NM_BOND_MODE_8023AD] = "802.3ad", + [NM_BOND_MODE_ACTIVEBACKUP] = "active-backup", + [NM_BOND_MODE_ALB] = "balance-alb", + [NM_BOND_MODE_BROADCAST] = "broadcast", + [NM_BOND_MODE_ROUNDROBIN] = "balance-rr", + [NM_BOND_MODE_TLB] = "balance-tlb", + [NM_BOND_MODE_XOR] = "balance-xor", + }; + + G_STATIC_ASSERT(G_N_ELEMENTS(modes) == _NM_BOND_MODE_NUM); + + if (NM_MORE_ASSERT_ONCE(5)) { + char sbuf[100]; + int i; + NMBondMode m; + + for (i = 0; i < (int) G_N_ELEMENTS(modes); i++) { + nm_assert(modes[i]); + nm_assert(i == _nm_setting_bond_mode_from_string(modes[i])); + nm_assert(i == _nm_setting_bond_mode_from_string(nm_sprintf_buf(sbuf, "%d", i))); + } + nm_assert(NM_BOND_MODE_UNKNOWN == _nm_setting_bond_mode_from_string(NULL)); + nm_assert(NM_BOND_MODE_UNKNOWN == _nm_setting_bond_mode_from_string("")); + for (i = -2; i < ((int) G_N_ELEMENTS(modes)) + 20; i++) { + if (i < 0 || i >= G_N_ELEMENTS(modes)) + m = NM_BOND_MODE_UNKNOWN; + else + m = i; + nm_assert(m == _nm_setting_bond_mode_from_string(nm_sprintf_buf(sbuf, "%d", i))); + } + } + + if (mode >= 0 && mode < (int) G_N_ELEMENTS(modes)) + return modes[mode]; + return NULL; +} + +/*****************************************************************************/ + +gboolean +nm_utils_vlan_priority_map_parse_str(NMVlanPriorityMap map_type, + const char * str, + gboolean allow_wildcard_to, + guint32 * out_from, + guint32 * out_to, + gboolean * out_has_wildcard_to) +{ + const char *s2; + gint64 v1, v2; + + nm_assert(str); + + s2 = strchr(str, ':'); + + if (!s2) { + if (!allow_wildcard_to) + return FALSE; + v1 = _nm_utils_ascii_str_to_int64(str, 10, 0, G_MAXUINT32, -1); + v2 = -1; + } else { + gs_free char *s1_free = NULL; + gsize s1_len = (s2 - str); + + s2 = nm_str_skip_leading_spaces(&s2[1]); + if (s2[0] == '\0' || (s2[0] == '*' && NM_STRCHAR_ALL(&s2[1], ch, g_ascii_isspace(ch)))) { + if (!allow_wildcard_to) + return FALSE; + v2 = -1; + } else { + v2 = _nm_utils_ascii_str_to_int64(s2, 10, 0, G_MAXUINT32, -1); + if (v2 < 0 || (guint32) v2 > nm_utils_vlan_priority_map_get_max_prio(map_type, FALSE)) + return FALSE; + } + + v1 = _nm_utils_ascii_str_to_int64(nm_strndup_a(100, str, s1_len, &s1_free), + 10, + 0, + G_MAXUINT32, + -1); + } + + if (v1 < 0 || (guint32) v1 > nm_utils_vlan_priority_map_get_max_prio(map_type, TRUE)) + return FALSE; + + NM_SET_OUT(out_from, v1); + NM_SET_OUT(out_to, v2 < 0 ? 0u : (guint) v2); + 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; +} + +gboolean +nm_utils_validate_dhcp4_vendor_class_id(const char *vci, GError **error) +{ + const char * bin; + gsize unescaped_len; + gs_free char *to_free = NULL; + + g_return_val_if_fail(!error || !(*error), FALSE); + g_return_val_if_fail(vci, FALSE); + + if (vci[0] == '\0') { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property cannot be an empty string")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER); + return FALSE; + } + + bin = nm_utils_buf_utf8safe_unescape(vci, + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, + &unescaped_len, + (gpointer *) &to_free); + /* a DHCP option cannot be longer than 255 bytes */ + if (unescaped_len > 255) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property cannot be longer than 255 bytes")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER); + return FALSE; + } + if (strlen(bin) != unescaped_len) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property cannot contain any nul bytes")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER); + return FALSE; + } + + return TRUE; +} + +gboolean +nm_settings_connection_validate_permission_user(const char *item, gssize len) +{ + gsize l; + + if (!item) + return FALSE; + + if (len < 0) { + nm_assert(len == -1); + l = strlen(item); + } else + l = (gsize) len; + + if (l == 0) + return FALSE; + + if (!g_utf8_validate(item, l, NULL)) + return FALSE; + + if (l >= 100) + return FALSE; + + if (memchr(item, ':', l)) + return FALSE; + + return TRUE; +} diff --git a/src/libnm-core-aux-intern/nm-libnm-core-utils.h b/src/libnm-core-aux-intern/nm-libnm-core-utils.h new file mode 100644 index 00000000..e0a6aaf1 --- /dev/null +++ b/src/libnm-core-aux-intern/nm-libnm-core-utils.h @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NM_LIBNM_SHARED_UTILS_H__ +#define __NM_LIBNM_SHARED_UTILS_H__ + +/****************************************************************************/ + +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-connection.h" +#include "nm-setting-ip-config.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-sriov.h" +#include "nm-setting-team.h" +#include "nm-setting-vlan.h" +#include "nm-setting-wireguard.h" + +/****************************************************************************/ + +#define nm_auto_unref_ip_address nm_auto(_nm_ip_address_unref) +NM_AUTO_DEFINE_FCN0(NMIPAddress *, _nm_ip_address_unref, nm_ip_address_unref); + +#define nm_auto_unref_ip_route nm_auto(_nm_auto_unref_ip_route) +NM_AUTO_DEFINE_FCN0(NMIPRoute *, _nm_auto_unref_ip_route, nm_ip_route_unref); + +#define nm_auto_unref_ip_routing_rule nm_auto(_nm_auto_unref_ip_routing_rule) +NM_AUTO_DEFINE_FCN0(NMIPRoutingRule *, _nm_auto_unref_ip_routing_rule, nm_ip_routing_rule_unref); + +#define nm_auto_unref_sriov_vf nm_auto(_nm_auto_unref_sriov_vf) +NM_AUTO_DEFINE_FCN0(NMSriovVF *, _nm_auto_unref_sriov_vf, nm_sriov_vf_unref); + +#define nm_auto_unref_tc_qdisc nm_auto(_nm_auto_unref_tc_qdisc) +NM_AUTO_DEFINE_FCN0(NMTCQdisc *, _nm_auto_unref_tc_qdisc, nm_tc_qdisc_unref); + +#define nm_auto_unref_tc_tfilter nm_auto(_nm_auto_unref_tc_tfilter) +NM_AUTO_DEFINE_FCN0(NMTCTfilter *, _nm_auto_unref_tc_tfilter, nm_tc_tfilter_unref); + +#define nm_auto_unref_tc_action nm_auto(_nm_auto_unref_tc_action) +NM_AUTO_DEFINE_FCN0(NMTCAction *, _nm_auto_unref_tc_action, nm_tc_action_unref); + +#define nm_auto_unref_bridge_vlan nm_auto(_nm_auto_unref_bridge_vlan) +NM_AUTO_DEFINE_FCN0(NMBridgeVlan *, _nm_auto_unref_bridge_vlan, nm_bridge_vlan_unref); + +#define nm_auto_unref_team_link_watcher nm_auto(_nm_auto_unref_team_link_watcher) +NM_AUTO_DEFINE_FCN0(NMTeamLinkWatcher *, + _nm_auto_unref_team_link_watcher, + nm_team_link_watcher_unref); + +#define nm_auto_unref_wgpeer nm_auto(_nm_auto_unref_wgpeer) +NM_AUTO_DEFINE_FCN0(NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref); + +/****************************************************************************/ + +const char **nm_utils_bond_option_arp_ip_targets_split(const char *arp_ip_target); + +void _nm_setting_bond_remove_options_miimon(NMSettingBond *s_bond); +void _nm_setting_bond_remove_options_arp_interval(NMSettingBond *s_bond); + +typedef enum { + NM_BOND_MODE_UNKNOWN = -1, + + /* The numeric values correspond to kernel's numbering of the modes. */ + NM_BOND_MODE_ROUNDROBIN = 0, + NM_BOND_MODE_ACTIVEBACKUP = 1, + NM_BOND_MODE_XOR = 2, + NM_BOND_MODE_BROADCAST = 3, + NM_BOND_MODE_8023AD = 4, + NM_BOND_MODE_TLB = 5, + NM_BOND_MODE_ALB = 6, + + _NM_BOND_MODE_NUM, +} NMBondMode; + +NMBondMode _nm_setting_bond_mode_from_string(const char *str); + +const char *_nm_setting_bond_mode_to_string(int mode); + +gboolean _nm_setting_bond_validate_option(const char *name, const char *value, GError **error); + +/*****************************************************************************/ + +static inline guint32 +nm_utils_vlan_priority_map_get_max_prio(NMVlanPriorityMap map, gboolean from) +{ + if (map == NM_VLAN_INGRESS_MAP) { + return from ? 7u /* MAX_8021P_PRIO */ + : (guint32) G_MAXUINT32 /* MAX_SKB_PRIO */; + } + nm_assert(map == NM_VLAN_EGRESS_MAP); + return from ? (guint32) G_MAXUINT32 /* MAX_SKB_PRIO */ + : 7u /* MAX_8021P_PRIO */; +} + +gboolean nm_utils_vlan_priority_map_parse_str(NMVlanPriorityMap map_type, + const char * str, + gboolean allow_wildcard_to, + guint32 * out_from, + guint32 * out_to, + gboolean * out_has_wildcard_to); + +/*****************************************************************************/ + +#define _NM_DEVICE_INTERFACE_FLAG_ALL \ + ((NMDeviceInterfaceFlags) (NM_DEVICE_INTERFACE_FLAG_UP | NM_DEVICE_INTERFACE_FLAG_LOWER_UP \ + | NM_DEVICE_INTERFACE_FLAG_CARRIER \ + | NM_DEVICE_INTERFACE_FLAG_PROMISC \ + | NM_DEVICE_INTERFACE_FLAG_LLDP_CLIENT_ENABLED)) + +/*****************************************************************************/ + +#define NM_OVS_EXTERNAL_ID_NM_PREFIX "NM." +#define NM_OVS_EXTERNAL_ID_NM_CONNECTION_UUID "NM.connection.uuid" + +/*****************************************************************************/ + +static inline int +nm_setting_ip_config_get_addr_family(NMSettingIPConfig *s_ip) +{ + if (NM_IS_SETTING_IP4_CONFIG(s_ip)) + return AF_INET; + if (NM_IS_SETTING_IP6_CONFIG(s_ip)) + return AF_INET6; + g_return_val_if_reached(AF_UNSPEC); +} + +/*****************************************************************************/ + +/* The maximum MTU for infiniband. + * + * This is both in transport-mode "datagram" and "connected" + * and they both have the same maximum define. + * + * Note that in the past, MTU in "datagram" mode was restricted + * to 2044 bytes. That is no longer the case and we accept large + * MTUs. + * + * This define is the maxiumum for the MTU in a connection profile (the + * setting). Whether large MTUs can be configured later (at activation time) + * depends on other factors. */ +#define NM_INFINIBAND_MAX_MTU ((guint) 65520) + +/*****************************************************************************/ + +#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); + +gboolean nm_utils_validate_dhcp4_vendor_class_id(const char *vci, GError **error); + +/*****************************************************************************/ + +#define NM_SETTINGS_CONNECTION_PERMISSION_USER "user" +#define NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX "user:" + +gboolean nm_settings_connection_validate_permission_user(const char *item, gssize len); + +#endif /* __NM_LIBNM_SHARED_UTILS_H__ */ |