Skip to content

Commit

Permalink
session-quit: Use a unique dialog server address for each session.
Browse files Browse the repository at this point in the history
This was preventing the logout dialog for subsequent users logged
in, as it would attempt to connect to the original user's server
(and be denied).

- A unique address will be generated at startup, and passed to
  the dialog when it is launched.
- Log output from the c-s-owned dialog process when debugging is
  enabled.

Fixes linuxmint/cinnamon#12021
  • Loading branch information
mtwebster committed Jan 18, 2024
1 parent 5284f5e commit 11f9699
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 4 deletions.
8 changes: 7 additions & 1 deletion cinnamon-session-quit/cinnamon-session-quit.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def __init__(self):
parser.add_argument("--no-prompt", dest="no_prompt", action='store_true',
help=_("Don't prompt for user confirmation"))
parser.add_argument("--sm-owned", action="store_true", help=argparse.SUPPRESS)
parser.add_argument("--sm-bus-id", dest="bus_id", action="store", help=argparse.SUPPRESS)
args = parser.parse_args()

self.dialog_response = ResponseCode.NONE
Expand All @@ -76,6 +77,11 @@ def __init__(self):
self.no_prompt = args.no_prompt
self.sm_owned = args.sm_owned

if self.sm_owned:
self.bus_id = args.bus_id
else:
self.bus_id = None

self.proxy = None
self.signal_handler_id = 0

Expand Down Expand Up @@ -164,7 +170,7 @@ def setup_proxy(self):

try:
connection = Gio.DBusConnection.new_for_address_sync(
config.DBUS_ADDRESS,
self.bus_id,
Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT,
None, None
)
Expand Down
62 changes: 59 additions & 3 deletions cinnamon-session/csm-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#define KEY_BLACKLIST "autostart-blacklist"
#define KEY_PREFER_HYBRID_SLEEP "prefer-hybrid-sleep"
#define KEY_SUSPEND_HIBERNATE "suspend-then-hibernate"
#define KEY_DEBUG "debug"

#define POWER_SETTINGS_SCHEMA "org.cinnamon.settings-daemon.plugins.power"
#define KEY_LOCK_ON_SUSPEND "lock-on-suspend"
Expand Down Expand Up @@ -125,6 +126,7 @@ struct CsmManagerPrivate
GDBusServer *dialog_server;
guint dialog_reg_id;
CsmLogoutAction dialog_action;
gchar *dialog_bus_address;

char *session_name;
gboolean is_fallback_session : 1;
Expand Down Expand Up @@ -2909,7 +2911,10 @@ register_manager (CsmManager *manager)

// Set up private controller interface for dialog
gchar *guid = g_dbus_generate_guid ();
GDBusServer *server = g_dbus_server_new_sync (DBUS_ADDRESS,
manager->priv->dialog_bus_address = g_strdup_printf ("%s-%s", DBUS_ADDRESS, guid);
g_debug ("Dialog server address: %s", manager->priv->dialog_bus_address);

GDBusServer *server = g_dbus_server_new_sync (manager->priv->dialog_bus_address,
G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER,
guid,
NULL, NULL, &error);
Expand Down Expand Up @@ -3529,6 +3534,9 @@ csm_manager_dispose (GObject *object)
manager->priv->dialog_reg_id = 0;
g_dbus_node_info_unref (introspection_data);
g_dbus_server_stop (manager->priv->dialog_server);
g_object_unref (manager->priv->dialog_server);
g_object_unref (manager->priv->dialog_connection);
g_free (manager->priv->dialog_bus_address);
}

if (manager->priv->clients != NULL) {
Expand Down Expand Up @@ -3918,6 +3926,34 @@ on_dialog_exited (GObject *source,
g_clear_object (&dialog_cancellable);
}

static void
on_dialog_read (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GInputStream *stream = G_INPUT_STREAM (source);

g_debug ("Session quit dialog read output");

gssize read = g_input_stream_read_finish (stream, result, NULL);
if (read > 0) {
g_debug ("Session quit dialog (self-owned) output: %.*s", (gint) read, (gchar *) user_data);
} else {
g_debug ("Session quit dialog (self-owned) stdout closed");
g_free (user_data);
g_input_stream_close (stream, NULL, NULL);
return;
}

g_input_stream_read_async (stream,
user_data,
1024,
G_PRIORITY_DEFAULT,
NULL,
(GAsyncReadyCallback) on_dialog_read,
user_data);
}

static void
terminate_dialog (void)
{
Expand All @@ -3934,7 +3970,7 @@ static void
launch_dialog (CsmManager *manager, const gchar *flag)
{
GError *error;
// return;

if (dialog_process != NULL) {
g_debug ("There's already a session-manager dialog");
return;
Expand All @@ -3951,12 +3987,20 @@ launch_dialog (CsmManager *manager, const gchar *flag)
const gchar *argv[] = {
"cinnamon-session-quit",
"--sm-owned",
"--sm-bus-id", manager->priv->dialog_bus_address,
flag,
NULL
};

gboolean debugging = g_settings_get_boolean (manager->priv->settings, KEY_DEBUG);
GSubprocessFlags flags = G_SUBPROCESS_FLAGS_NONE;

if (debugging) {
flags = G_SUBPROCESS_FLAGS_STDERR_MERGE | G_SUBPROCESS_FLAGS_STDOUT_PIPE;
}

error = NULL;
dialog_process = g_subprocess_newv (argv, G_SUBPROCESS_FLAGS_NONE, &error);
dialog_process = g_subprocess_newv (argv, flags, &error);

if (dialog_process == NULL) {
if (error != NULL) {
Expand All @@ -3966,6 +4010,18 @@ launch_dialog (CsmManager *manager, const gchar *flag)
}
}

if (debugging) {
GInputStream *stdout = g_subprocess_get_stdout_pipe (dialog_process);
guint8 *buffer = g_malloc (1024);
g_input_stream_read_async (G_INPUT_STREAM (stdout),
buffer,
1024,
G_PRIORITY_DEFAULT,
NULL,
(GAsyncReadyCallback) on_dialog_read,
buffer);
}

dialog_cancellable = g_cancellable_new ();

g_subprocess_wait_async (dialog_process,
Expand Down

0 comments on commit 11f9699

Please sign in to comment.