From 1e45865e4ff625698d7e9c86f0666b9896dc8e6c Mon Sep 17 00:00:00 2001 From: Antonio Cardace Date: Tue, 17 Dec 2019 20:36:18 +0100 Subject: [PATCH] shared: nm-auth-subject: add unix-session type --- shared/nm-libnm-core-intern/nm-auth-subject.c | 125 +++++++++++++----- shared/nm-libnm-core-intern/nm-auth-subject.h | 20 +-- src/nm-active-connection.c | 4 +- src/nm-audit-manager.c | 3 +- src/nm-auth-manager.c | 4 +- src/nm-auth-utils.c | 20 ++- src/nm-manager.c | 8 +- src/nm-policy.c | 3 +- src/settings/nm-agent-manager.c | 8 +- src/settings/nm-secret-agent.c | 3 +- 10 files changed, 134 insertions(+), 64 deletions(-) diff --git a/shared/nm-libnm-core-intern/nm-auth-subject.c b/shared/nm-libnm-core-intern/nm-auth-subject.c index 2597867a56..96bc6b0887 100644 --- a/shared/nm-libnm-core-intern/nm-auth-subject.c +++ b/shared/nm-libnm-core-intern/nm-auth-subject.c @@ -23,6 +23,7 @@ enum { PROP_UNIX_PROCESS_DBUS_SENDER, PROP_UNIX_PROCESS_PID, PROP_UNIX_PROCESS_UID, + PROP_UNIX_SESSION_ID, PROP_LAST, }; @@ -35,6 +36,10 @@ typedef struct { guint64 start_time; char *dbus_sender; } unix_process; + + struct { + char *id; + } unix_session; } NMAuthSubjectPrivate; struct _NMAuthSubject { @@ -76,6 +81,10 @@ nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len) 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; @@ -85,23 +94,32 @@ nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len) /* returns a floating variant */ GVariant * -nm_auth_subject_unix_process_to_polkit_gvariant (NMAuthSubject *self) +nm_auth_subject_unix_to_polkit_gvariant (NMAuthSubject *self) { GVariantBuilder builder; - GVariant *dict; - GVariant *ret; - CHECK_SUBJECT_TYPED (self, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL); + CHECK_SUBJECT (self, NULL); - 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)); - dict = g_variant_builder_end (&builder); - ret = g_variant_new ("(s@a{sv})", "unix-process", dict); - return ret; + 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 @@ -112,18 +130,6 @@ nm_auth_subject_get_subject_type (NMAuthSubject *subject) return priv->subject_type; } -gboolean -nm_auth_subject_is_internal (NMAuthSubject *subject) -{ - return nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL; -} - -gboolean -nm_auth_subject_is_unix_process (NMAuthSubject *subject) -{ - return nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; -} - gulong nm_auth_subject_get_unix_process_pid (NMAuthSubject *subject) { @@ -148,6 +154,14 @@ nm_auth_subject_get_unix_process_dbus_sender (NMAuthSubject *subject) 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; +} + /*****************************************************************************/ /** @@ -165,10 +179,26 @@ nm_auth_subject_new_internal (void) 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 give unix process. + * Creates a new auth subject representing a given unix process. * * Returns: the new #NMAuthSubject */ @@ -176,11 +206,11 @@ 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_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)); } /** @@ -216,6 +246,9 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) 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; @@ -235,7 +268,10 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *p 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)); + 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); @@ -264,6 +300,14 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *p 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; @@ -278,7 +322,9 @@ _clear_private (NMAuthSubject *self) priv->subject_type = NM_AUTH_SUBJECT_TYPE_INVALID; priv->unix_process.pid = G_MAXULONG; priv->unix_process.uid = G_MAXULONG; - g_clear_pointer (&priv->unix_process.dbus_sender, g_free); + nm_clear_g_free (&priv->unix_process.dbus_sender); + + nm_clear_g_free (&priv->unix_session.id); } static void @@ -328,6 +374,8 @@ constructed (GObject *object) * start-time, but polkit is not. */ } return; + case NM_AUTH_SUBJECT_TYPE_UNIX_SESSION: + return; default: break; } @@ -358,7 +406,7 @@ nm_auth_subject_class_init (NMAuthSubjectClass *config_class) (object_class, PROP_SUBJECT_TYPE, g_param_spec_int (NM_AUTH_SUBJECT_SUBJECT_TYPE, "", "", NM_AUTH_SUBJECT_TYPE_INVALID, - NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, + NM_AUTH_SUBJECT_TYPE_UNIX_SESSION, NM_AUTH_SUBJECT_TYPE_INVALID, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | @@ -388,4 +436,11 @@ nm_auth_subject_class_init (NMAuthSubjectClass *config_class) 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 index 9454e7f7ee..e885c4ea96 100644 --- a/shared/nm-libnm-core-intern/nm-auth-subject.h +++ b/shared/nm-libnm-core-intern/nm-auth-subject.h @@ -17,12 +17,14 @@ 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_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; @@ -31,24 +33,24 @@ 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); -gboolean nm_auth_subject_is_internal (NMAuthSubject *subject); - -gboolean nm_auth_subject_is_unix_process (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_process_to_polkit_gvariant (NMAuthSubject *self); +GVariant *nm_auth_subject_unix_to_polkit_gvariant (NMAuthSubject *self); #endif /* __NETWORKMANAGER_AUTH_SUBJECT_H__ */ diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 3e333f405b..7b5053a5b6 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -598,7 +598,9 @@ nm_active_connection_get_user_requested (NMActiveConnection *self) { g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE); - return nm_auth_subject_is_unix_process (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject); + return nm_auth_subject_get_subject_type ( + NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject + ) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; } NMDevice * diff --git a/src/nm-audit-manager.c b/src/nm-audit-manager.c index 54ecb796e1..26ba48f528 100644 --- a/src/nm-audit-manager.c +++ b/src/nm-audit-manager.c @@ -200,7 +200,8 @@ _audit_log_helper (NMAuditManager *self, } else g_warn_if_reached (); } - if (subject && nm_auth_subject_is_unix_process (subject)) { + if (subject && + nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) { pid = nm_auth_subject_get_unix_process_pid (subject); uid = nm_auth_subject_get_unix_process_uid (subject); if (pid != G_MAXULONG) { diff --git a/src/nm-auth-manager.c b/src/nm-auth-manager.c index 3f248aeeec..186d56e41f 100644 --- a/src/nm-auth-manager.c +++ b/src/nm-auth-manager.c @@ -322,7 +322,7 @@ nm_auth_manager_check_authorization (NMAuthManager *self, }; c_list_link_tail (&priv->calls_lst_head, &call_id->calls_lst); - if (nm_auth_subject_is_internal (subject)) { + if (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL) { _LOG2T (call_id, "CheckAuthorization(%s), subject=%s (succeeding for internal request)", action_id, nm_auth_subject_to_string (subject, subject_buf, sizeof (subject_buf))); call_id->idle_id = g_idle_add (_call_on_idle, call_id); } else if (nm_auth_subject_get_unix_process_uid (subject) == 0) { @@ -339,7 +339,7 @@ nm_auth_manager_check_authorization (NMAuthManager *self, GVariant *subject_value; GVariant *details_value; - subject_value = nm_auth_subject_unix_process_to_polkit_gvariant (subject); + subject_value = nm_auth_subject_unix_to_polkit_gvariant (subject); nm_assert (g_variant_is_floating (subject_value)); /* ((PolkitDetails *)NULL) */ diff --git a/src/nm-auth-utils.c b/src/nm-auth-utils.c index c7acdc02a3..099fcfbfc3 100644 --- a/src/nm-auth-utils.c +++ b/src/nm-auth-utils.c @@ -342,8 +342,10 @@ nm_auth_chain_add_call_unsafe (NMAuthChain *self, g_return_if_fail (!self->is_finishing); g_return_if_fail (!self->is_destroyed); g_return_if_fail (permission && *permission); - nm_assert ( nm_auth_subject_is_unix_process (self->subject) - || nm_auth_subject_is_internal (self->subject)); + nm_assert ( nm_auth_subject_get_subject_type (self->subject) + == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS + || nm_auth_subject_get_subject_type (self->subject) + == NM_AUTH_SUBJECT_TYPE_INTERNAL); /* duplicate permissions are not supported, also because nm_auth_chain_get_result() * can only return one-permission. */ @@ -417,8 +419,10 @@ nm_auth_chain_new_subject (NMAuthSubject *subject, NMAuthChain *self; g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); - nm_assert ( nm_auth_subject_is_unix_process (subject) - || nm_auth_subject_is_internal (subject)); + nm_assert ( nm_auth_subject_get_subject_type (subject) + == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS + || nm_auth_subject_get_subject_type (subject) + == NM_AUTH_SUBJECT_TYPE_INTERNAL); nm_assert (done_func); self = g_slice_new (NMAuthChain); @@ -505,10 +509,12 @@ nm_auth_is_subject_in_acl (NMConnection *connection, g_return_val_if_fail (connection, FALSE); g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), FALSE); - nm_assert ( nm_auth_subject_is_internal (subject) - || nm_auth_subject_is_unix_process (subject)); + nm_assert ( nm_auth_subject_get_subject_type (subject) + == NM_AUTH_SUBJECT_TYPE_INTERNAL + || nm_auth_subject_get_subject_type (subject) + == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); - if (nm_auth_subject_is_internal (subject)) + if (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL) return TRUE; uid = nm_auth_subject_get_unix_process_uid (subject); diff --git a/src/nm-manager.c b/src/nm-manager.c index 3085ba9a49..1b00b1d320 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -4514,7 +4514,7 @@ unmanaged_to_disconnected (NMDevice *device) static NMActivationStateFlags _activation_bind_lifetime_to_profile_visibility (NMAuthSubject *subject) { - if ( nm_auth_subject_is_internal (subject) + if ( nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL || nm_auth_subject_get_unix_process_uid (subject) == 0) { /* internal requests and requests from root are always unbound. */ return NM_ACTIVATION_STATE_FLAG_NONE; @@ -5098,8 +5098,10 @@ nm_manager_activate_connection (NMManager *self, if ( sett_conn == nm_active_connection_get_settings_connection (active) && nm_streq0 (nm_active_connection_get_specific_object (active), specific_object) && (!device || nm_active_connection_get_device (active) == device) - && nm_auth_subject_is_internal (nm_active_connection_get_subject (active)) - && nm_auth_subject_is_internal (subject) + && nm_auth_subject_get_subject_type (nm_active_connection_get_subject (active)) + == NM_AUTH_SUBJECT_TYPE_INTERNAL + && nm_auth_subject_get_subject_type (subject) + == NM_AUTH_SUBJECT_TYPE_INTERNAL && nm_active_connection_get_activation_reason (active) == activation_reason) return active; } diff --git a/src/nm-policy.c b/src/nm-policy.c index 7fd818b675..56bec87b3d 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1633,7 +1633,8 @@ activate_slave_connections (NMPolicy *self, NMDevice *device) } subject = nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)); - internal_activation = subject && nm_auth_subject_is_internal (subject); + internal_activation = subject + && (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL); } changed = FALSE; diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 53dd953af8..af6358a360 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -626,7 +626,7 @@ agent_compare_func (gconstpointer aa, gconstpointer bb, gpointer user_data) b_pid = nm_secret_agent_get_pid (b); /* Prefer agents in the process the request came from */ - if (nm_auth_subject_is_unix_process (req->subject)) { + if (nm_auth_subject_get_subject_type (req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) { requester = nm_auth_subject_get_unix_process_pid (req->subject); if (a_pid != b_pid) { @@ -682,7 +682,7 @@ request_add_agent (Request *req, NMSecretAgent *agent) } /* If the request should filter agents by UID, do that now */ - if (nm_auth_subject_is_unix_process (req->subject)) { + if (nm_auth_subject_get_subject_type (req->subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) { uid_t agent_uid, subject_uid; agent_uid = nm_secret_agent_get_owner_uid (agent); @@ -1409,8 +1409,8 @@ nm_agent_manager_all_agents_have_capability (NMAgentManager *manager, NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (manager); GHashTableIter iter; NMSecretAgent *agent; - gboolean subject_is_unix_process = nm_auth_subject_is_unix_process (subject); - gulong subject_uid = subject_is_unix_process ? nm_auth_subject_get_unix_process_uid (subject) : 0; + gboolean subject_is_unix_process = (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + gulong subject_uid = subject_is_unix_process ? nm_auth_subject_get_unix_process_uid (subject) : 0u; g_hash_table_iter_init (&iter, priv->agents); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &agent)) { diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index d550ada740..82a8c904a5 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -709,7 +709,8 @@ nm_secret_agent_new (GDBusMethodInvocation *context, g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); - g_return_val_if_fail (nm_auth_subject_is_unix_process (subject), NULL); + g_return_val_if_fail (nm_auth_subject_get_subject_type (subject) + == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL); g_return_val_if_fail (identifier != NULL, NULL); dbus_connection = g_dbus_method_invocation_get_connection (context);