gboolean 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); }
static void _audit_log_helper (NMAuditManager *self, GPtrArray *fields, const char *file, guint line, const char *func, const char *op, gboolean result, gpointer subject_context, const char *reason) { AuditField op_field = { }, pid_field = { }, uid_field = { }; AuditField result_field = { }, reason_field = { }; gulong pid, uid; NMAuthSubject *subject = NULL; gs_unref_object NMAuthSubject *subject_free = NULL; _audit_field_init_string (&op_field, "op", op, FALSE, BACKEND_ALL); g_ptr_array_insert (fields, 0, &op_field); if (subject_context) { if (NM_IS_AUTH_SUBJECT (subject_context)) subject = subject_context; else if (G_IS_DBUS_METHOD_INVOCATION (subject_context)) { GDBusMethodInvocation *context = subject_context; subject = subject_free = nm_auth_subject_new_unix_process_from_context (context); } else g_warn_if_reached (); } if (subject && nm_auth_subject_is_unix_process (subject)) { pid = nm_auth_subject_get_unix_process_pid (subject); uid = nm_auth_subject_get_unix_process_uid (subject); if (pid != G_MAXULONG) { _audit_field_init_uint (&pid_field, "pid", pid, BACKEND_ALL); g_ptr_array_add (fields, &pid_field); } if (uid != G_MAXULONG) { _audit_field_init_uint (&uid_field, "uid", uid, BACKEND_ALL); g_ptr_array_add (fields, &uid_field); } } _audit_field_init_string (&result_field, "result", result ? "success" : "fail", FALSE, BACKEND_ALL); g_ptr_array_add (fields, &result_field); if (reason) { _audit_field_init_string (&reason_field, "reason", reason, FALSE, BACKEND_LOG); g_ptr_array_add (fields, &reason_field); } nm_audit_log (self, fields, file, line, func, result); }
NMSecretAgent * nm_secret_agent_new (DBusGMethodInvocation *context, NMAuthSubject *subject, const char *identifier, NMSecretAgentCapabilities capabilities) { NMSecretAgent *self; NMSecretAgentPrivate *priv; char *hash_str, *username; struct passwd *pw; 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 (identifier != NULL, NULL); pw = getpwuid (nm_auth_subject_get_unix_process_uid (subject)); g_return_val_if_fail (pw != NULL, NULL); g_return_val_if_fail (pw->pw_name[0] != '\0', NULL); username = g_strdup (pw->pw_name); self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL); priv = NM_SECRET_AGENT_GET_PRIVATE (self); priv->identifier = g_strdup (identifier); priv->owner_username = g_strdup (username); priv->capabilities = capabilities; priv->subject = g_object_ref (subject); hash_str = g_strdup_printf ("%16lu%s", nm_auth_subject_get_unix_process_uid (subject), identifier); priv->hash = g_str_hash (hash_str); g_free (hash_str); priv->proxy = nm_dbus_manager_new_proxy (nm_dbus_manager_get (), context, nm_auth_subject_get_unix_process_dbus_sender (subject), NM_DBUS_PATH_SECRET_AGENT, NM_DBUS_INTERFACE_SECRET_AGENT); g_assert (priv->proxy); priv->proxy_destroy_id = g_signal_connect_swapped (priv->proxy, "destroy", G_CALLBACK (proxy_cleanup), self); g_free (username); return self; }
gboolean nm_auth_is_subject_in_acl (NMConnection *connection, NMAuthSubject *subject, char **out_error_desc) { NMSettingConnection *s_con; const char *user = NULL; gulong uid; g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), FALSE); g_return_val_if_fail (nm_auth_subject_is_internal (subject) || nm_auth_subject_is_unix_process (subject), FALSE); if (nm_auth_subject_is_internal (subject)) return TRUE; uid = nm_auth_subject_get_unix_process_uid (subject); /* Root gets a free pass */ if (0 == uid) return TRUE; if (!nm_session_monitor_uid_to_user (uid, &user)) { if (out_error_desc) *out_error_desc = g_strdup_printf ("Could not determine username for uid %lu", uid); return FALSE; } s_con = nm_connection_get_setting_connection (connection); if (!s_con) { /* This can only happen when called from AddAndActivate, so we know * the user will be authorized when the connection is completed. */ return TRUE; } /* Match the username returned by the session check to a user in the ACL */ if (!nm_setting_connection_permissions_user_allowed (s_con, user)) { if (out_error_desc) *out_error_desc = g_strdup_printf ("uid %lu has no permission to perform this operation", uid); return FALSE; } return TRUE; }
void nm_auth_chain_add_call (NMAuthChain *self, const char *permission, gboolean allow_interaction) { AuthCall *call; NMAuthManager *auth_manager = nm_auth_manager_get (); g_return_if_fail (self != NULL); g_return_if_fail (permission && *permission); g_return_if_fail (self->subject); g_return_if_fail (nm_auth_subject_is_unix_process (self->subject) || nm_auth_subject_is_internal (self->subject)); g_return_if_fail (!self->idle_id && !self->done); call = auth_call_new (self, permission); self->calls = g_slist_append (self->calls, call); if ( nm_auth_subject_is_internal (self->subject) || nm_auth_subject_get_unix_process_uid (self->subject) == 0 || !nm_auth_manager_get_polkit_enabled (auth_manager)) { /* Root user or non-polkit always gets the permission */ nm_auth_chain_set_data (self, permission, GUINT_TO_POINTER (NM_AUTH_CALL_RESULT_YES), NULL); call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); } else { /* Non-root always gets authenticated when using polkit */ #if WITH_POLKIT call->cancellable = g_cancellable_new (); nm_auth_manager_polkit_authority_check_authorization (auth_manager, self->subject, permission, allow_interaction, call->cancellable, pk_call_cb, call); #else if (!call->chain->error) { call->chain->error = g_error_new_literal (DBUS_GERROR, DBUS_GERROR_FAILED, "Polkit support is disabled at compile time"); } call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); #endif } }
/* Requires an NMAuthSubject */ NMAuthChain * nm_auth_chain_new_subject (NMAuthSubject *subject, GDBusMethodInvocation *context, NMAuthChainResultFunc done_func, gpointer user_data) { NMAuthChain *self; g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); g_return_val_if_fail (nm_auth_subject_is_unix_process (subject) || nm_auth_subject_is_internal (subject), NULL); self = g_slice_new0 (NMAuthChain); self->refcount = 1; self->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, chain_data_free); self->done_func = done_func; self->user_data = user_data; self->context = context ? g_object_ref (context) : NULL; self->subject = g_object_ref (subject); return self; }