mirror of
https://github.com/morgan9e/grd
synced 2026-04-14 00:14:18 +09:00
.
This commit is contained in:
232
grd-daemon-utils.c
Normal file
232
grd-daemon-utils.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2023 SUSE Software Solutions Germany GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "grd-daemon-utils.h"
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
|
||||
enum
|
||||
{
|
||||
GSM_LOGOUT_MODE_NORMAL = 0,
|
||||
GSM_LOGOUT_MODE_NO_CONFIRMATION,
|
||||
GSM_LOGOUT_MODE_FORCE,
|
||||
};
|
||||
|
||||
gboolean
|
||||
grd_get_pid_of_sender_sync (GDBusConnection *connection,
|
||||
const char *name,
|
||||
pid_t *out_pid,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr (GVariant) result = NULL;
|
||||
uint32_t pid;
|
||||
|
||||
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
g_assert (out_pid);
|
||||
|
||||
result = g_dbus_connection_call_sync (connection,
|
||||
"org.freedesktop.DBus",
|
||||
"/org/freedesktop/DBus",
|
||||
"org.freedesktop.DBus",
|
||||
"GetConnectionUnixProcessID",
|
||||
g_variant_new ("(s)", name),
|
||||
G_VARIANT_TYPE ("(u)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable, error);
|
||||
if (!result)
|
||||
return FALSE;
|
||||
|
||||
g_variant_get (result, "(u)", &pid);
|
||||
|
||||
*out_pid = (pid_t) pid;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
grd_get_uid_of_sender_sync (GDBusConnection *connection,
|
||||
const char *name,
|
||||
uid_t *out_uid,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr (GVariant) result = NULL;
|
||||
uint32_t uid;
|
||||
|
||||
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
g_assert (out_uid);
|
||||
|
||||
result = g_dbus_connection_call_sync (connection,
|
||||
"org.freedesktop.DBus",
|
||||
"/org/freedesktop/DBus",
|
||||
"org.freedesktop.DBus",
|
||||
"GetConnectionUnixUser",
|
||||
g_variant_new ("(s)", name),
|
||||
G_VARIANT_TYPE ("(u)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable, error);
|
||||
if (!result)
|
||||
return FALSE;
|
||||
|
||||
g_variant_get (result, "(u)", &uid);
|
||||
|
||||
*out_uid = (uid_t) uid;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *
|
||||
grd_get_session_id_from_pid (pid_t pid)
|
||||
{
|
||||
char *session_id = NULL;
|
||||
int res;
|
||||
|
||||
res = sd_pid_get_session (pid, &session_id);
|
||||
if (res < 0 && res != -ENODATA)
|
||||
{
|
||||
g_warning ("Failed to retrieve session information for "
|
||||
"pid %d: %s", (int) pid, strerror (-res));
|
||||
}
|
||||
|
||||
return g_steal_pointer (&session_id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
grd_sd_session_is_graphical (const char *session_id)
|
||||
{
|
||||
const char * const graphical_session_types[] = { "wayland", "x11", NULL };
|
||||
int res;
|
||||
g_autofree char *type = NULL;
|
||||
|
||||
res = sd_session_get_type (session_id, &type);
|
||||
if (res < 0)
|
||||
return FALSE;
|
||||
|
||||
return g_strv_contains (graphical_session_types, type);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
grd_sd_session_is_active (const char *session_id)
|
||||
{
|
||||
const char * const active_states[] = { "active", "online", NULL };
|
||||
int res;
|
||||
g_autofree char *state = NULL;
|
||||
|
||||
res = sd_session_get_state (session_id, &state);
|
||||
if (res < 0)
|
||||
return FALSE;
|
||||
|
||||
return g_strv_contains (active_states, state);
|
||||
}
|
||||
|
||||
char *
|
||||
grd_get_session_id_from_uid (uid_t uid)
|
||||
{
|
||||
g_auto (GStrv) sessions = NULL;
|
||||
char *session_id = NULL;
|
||||
int n_sessions;
|
||||
int i;
|
||||
|
||||
n_sessions = sd_uid_get_sessions (uid, 0, &sessions);
|
||||
|
||||
for (i = n_sessions - 1; i >= 0; i--)
|
||||
{
|
||||
if (!grd_sd_session_is_graphical (sessions[i]))
|
||||
continue;
|
||||
|
||||
if (!grd_sd_session_is_active (sessions[i]))
|
||||
continue;
|
||||
|
||||
session_id = sessions[i];
|
||||
break;
|
||||
}
|
||||
|
||||
return g_strdup (session_id);
|
||||
}
|
||||
|
||||
gboolean
|
||||
grd_is_remote_login (void)
|
||||
{
|
||||
g_autofree char *session_id = NULL;
|
||||
g_autofree char *class = NULL;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
int ret;
|
||||
|
||||
pid = getpid ();
|
||||
session_id = grd_get_session_id_from_pid (pid);
|
||||
if (!session_id)
|
||||
{
|
||||
uid = getuid ();
|
||||
session_id = grd_get_session_id_from_uid (uid);
|
||||
}
|
||||
|
||||
if (!session_id)
|
||||
{
|
||||
g_warning ("Couldn't get session id");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = sd_session_get_class (session_id, &class);
|
||||
if (ret < 0)
|
||||
{
|
||||
g_warning ("Couldn't determine session class: %s", g_strerror (-ret));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return g_strcmp0 (class, "greeter") == 0 &&
|
||||
sd_session_is_remote (session_id) == 1;
|
||||
}
|
||||
|
||||
void
|
||||
grd_session_manager_call_logout_sync (void)
|
||||
{
|
||||
g_autoptr (GDBusConnection) connection = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||
if (!connection)
|
||||
{
|
||||
g_warning ("Couldn't get session bus to logout: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
g_dbus_connection_call_sync (connection,
|
||||
"org.gnome.SessionManager",
|
||||
"/org/gnome/SessionManager",
|
||||
"org.gnome.SessionManager",
|
||||
"Logout",
|
||||
g_variant_new ("(u)",
|
||||
GSM_LOGOUT_MODE_NO_CONFIRMATION),
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL, &error);
|
||||
if (error)
|
||||
g_warning ("Couldn't logout of session: %s", error->message);
|
||||
}
|
||||
Reference in New Issue
Block a user