1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29
#include <sys/types.h>
37
#include <glib/gstdio.h>
38
#include <glib/gi18n.h>
39
#include <glib-object.h>
41
#include <X11/Xlib.h> /* for Display */
42
#include <X11/Xatom.h> /* for XA_PIXMAP */
43
#include <X11/cursorfont.h> /* for watch cursor */
44
#include <X11/extensions/Xrandr.h>
45
#include <X11/Xatom.h>
48
#include <systemd/sd-login.h>
49
#include <systemd/sd-daemon.h>
52
#include "gdm-common.h"
53
#include "gdm-xerrors.h"
55
#include "gdm-slave.h"
56
#include "gdm-slave-glue.h"
57
#include "gdm-display-glue.h"
59
#include "gdm-server.h"
61
#define GDM_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SLAVE, GdmSlavePrivate))
63
#define CK_NAME "org.freedesktop.ConsoleKit"
64
#define CK_PATH "/org/freedesktop/ConsoleKit"
65
#define CK_INTERFACE "org.freedesktop.ConsoleKit"
67
#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
68
#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
69
#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
70
#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
72
#define GDM_DBUS_NAME "org.gnome.DisplayManager"
73
#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
75
#define GDM_SLAVE_PATH "/org/gnome/DisplayManager/Slave"
77
#define MAX_CONNECT_ATTEMPTS 10
79
struct GdmSlavePrivate
82
guint output_watch_id;
85
Display *server_display;
89
/* cached display values */
93
char *display_hostname;
94
gboolean display_is_local;
95
gboolean display_is_parented;
96
char *display_seat_id;
97
char *display_x11_authority_file;
98
char *parent_display_name;
99
char *parent_display_x11_authority_file;
101
char *display_x11_cookie;
102
gboolean display_is_initial;
104
GdmDBusDisplay *display_proxy;
105
GDBusConnection *connection;
106
GdmDBusSlave *skeleton;
115
PROP_DISPLAY_HOSTNAME,
116
PROP_DISPLAY_IS_LOCAL,
117
PROP_DISPLAY_SEAT_ID,
118
PROP_DISPLAY_X11_AUTHORITY_FILE,
119
PROP_DISPLAY_IS_INITIAL,
127
static guint signals [LAST_SIGNAL] = { 0, };
129
static void gdm_slave_class_init (GdmSlaveClass *klass);
130
static void gdm_slave_init (GdmSlave *slave);
131
static void gdm_slave_finalize (GObject *object);
133
G_DEFINE_ABSTRACT_TYPE (GdmSlave, gdm_slave, G_TYPE_OBJECT)
135
#define CURSOR_WATCH XC_watch
138
gdm_slave_error_quark (void)
140
static GQuark ret = 0;
142
ret = g_quark_from_static_string ("gdm-slave-error-quark");
149
gdm_slave_whack_temp_auth_file (GdmSlave *slave)
157
if (d->parent_temp_auth_file != NULL) {
158
VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file));
160
g_free (d->parent_temp_auth_file);
161
d->parent_temp_auth_file = NULL;
169
create_temp_auth_file (GdmSlave *slave)
172
if (d->type == TYPE_FLEXI_XNEST &&
173
d->parent_auth_file != NULL) {
174
if (d->parent_temp_auth_file != NULL) {
175
VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file));
177
g_free (d->parent_temp_auth_file);
178
d->parent_temp_auth_file =
179
copy_auth_file (d->server_uid,
180
gdm_daemon_config_get_gdmuid (),
181
d->parent_auth_file);
187
listify_hash (const char *key,
192
str = g_strdup_printf ("%s=%s", key, value);
193
g_debug ("GdmSlave: script environment: %s", str);
194
g_ptr_array_add (env, str);
198
get_script_environment (GdmSlave *slave,
199
const char *username)
203
struct passwd *pwent;
204
char *x_servers_file;
207
env = g_ptr_array_new ();
209
/* create a hash table of current environment, then update keys has necessary */
210
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
212
/* modify environment here */
213
g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/"));
214
g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/"));
215
g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh"));
217
if (username != NULL) {
218
g_hash_table_insert (hash, g_strdup ("LOGNAME"),
219
g_strdup (username));
220
g_hash_table_insert (hash, g_strdup ("USER"),
221
g_strdup (username));
222
g_hash_table_insert (hash, g_strdup ("USERNAME"),
223
g_strdup (username));
225
gdm_get_pwent_for_name (username, &pwent);
227
if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') {
228
g_hash_table_insert (hash, g_strdup ("HOME"),
229
g_strdup (pwent->pw_dir));
230
g_hash_table_insert (hash, g_strdup ("PWD"),
231
g_strdup (pwent->pw_dir));
234
g_hash_table_insert (hash, g_strdup ("SHELL"),
235
g_strdup (pwent->pw_shell));
240
if (display_is_parented) {
241
g_hash_table_insert (hash, g_strdup ("GDM_PARENT_DISPLAY"), g_strdup (parent_display_name));
243
/*g_hash_table_insert (hash, "GDM_PARENT_XAUTHORITY"), slave->priv->parent_temp_auth_file));*/
247
/* some env for use with the Pre and Post scripts */
248
temp = g_strconcat (slave->priv->display_name, ".Xservers", NULL);
249
x_servers_file = g_build_filename (AUTHDIR, temp, NULL);
252
g_hash_table_insert (hash, g_strdup ("X_SERVERS"), x_servers_file);
254
if (! slave->priv->display_is_local) {
255
g_hash_table_insert (hash, g_strdup ("REMOTE_HOST"), g_strdup (slave->priv->display_hostname));
259
g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (slave->priv->display_x11_authority_file));
260
g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (slave->priv->display_name));
261
g_hash_table_insert (hash, g_strdup ("PATH"), g_strdup (GDM_SESSION_DEFAULT_PATH));
262
g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true"));
264
g_hash_table_remove (hash, "MAIL");
267
g_hash_table_foreach (hash, (GHFunc)listify_hash, env);
268
g_hash_table_destroy (hash);
270
g_ptr_array_add (env, NULL);
276
gdm_slave_run_script (GdmSlave *slave,
290
g_assert (dir != NULL);
291
g_assert (login != NULL);
293
script = g_build_filename (dir, slave->priv->display_name, NULL);
294
g_debug ("GdmSlave: Trying script %s", script);
295
if (! (g_file_test (script, G_FILE_TEST_IS_REGULAR)
296
&& g_file_test (script, G_FILE_TEST_IS_EXECUTABLE))) {
297
g_debug ("GdmSlave: script %s not found; skipping", script);
303
&& slave->priv->display_hostname != NULL
304
&& slave->priv->display_hostname[0] != '\0') {
305
script = g_build_filename (dir, slave->priv->display_hostname, NULL);
306
g_debug ("GdmSlave: Trying script %s", script);
307
if (! (g_file_test (script, G_FILE_TEST_IS_REGULAR)
308
&& g_file_test (script, G_FILE_TEST_IS_EXECUTABLE))) {
309
g_debug ("GdmSlave: script %s not found; skipping", script);
315
if (script == NULL) {
316
script = g_build_filename (dir, "Default", NULL);
317
g_debug ("GdmSlave: Trying script %s", script);
318
if (! (g_file_test (script, G_FILE_TEST_IS_REGULAR)
319
&& g_file_test (script, G_FILE_TEST_IS_EXECUTABLE))) {
320
g_debug ("GdmSlave: script %s not found; skipping", script);
326
if (script == NULL) {
327
g_debug ("GdmSlave: no script found");
331
create_temp_auth_file (slave);
333
g_debug ("GdmSlave: Running process: %s", script);
335
if (! g_shell_parse_argv (script, NULL, &argv, &error)) {
336
g_warning ("Could not parse command: %s", error->message);
337
g_error_free (error);
341
env = get_script_environment (slave, login);
343
res = g_spawn_sync (NULL,
354
g_ptr_array_foreach (env, (GFunc)g_free, NULL);
355
g_ptr_array_free (env, TRUE);
359
g_warning ("GdmSlave: Unable to run script: %s", error->message);
360
g_error_free (error);
363
gdm_slave_whack_temp_auth_file (slave);
365
if (WIFEXITED (status)) {
366
g_debug ("GdmSlave: Process exit status: %d", WEXITSTATUS (status));
367
ret = WEXITSTATUS (status) == 0;
377
gdm_slave_save_root_window_of_screen (GdmSlave *slave,
385
int width, height, depth;
387
root_window = RootWindow (slave->priv->server_display,
390
width = DisplayWidth (slave->priv->server_display, screen_number);
391
height = DisplayHeight (slave->priv->server_display, screen_number);
392
depth = DefaultDepth (slave->priv->server_display, screen_number);
393
pixmap = XCreatePixmap (slave->priv->server_display,
395
width, height, depth);
397
values.function = GXcopy;
398
values.plane_mask = AllPlanes;
399
values.fill_style = FillSolid;
400
values.subwindow_mode = IncludeInferiors;
402
gc = XCreateGC (slave->priv->server_display,
404
GCFunction | GCPlaneMask | GCFillStyle | GCSubwindowMode,
407
if (XCopyArea (slave->priv->server_display,
408
root_window, pixmap, gc, 0, 0,
409
width, height, 0, 0)) {
413
pixmap_as_long = (long) pixmap;
415
XChangeProperty (slave->priv->server_display,
416
root_window, id_atom, XA_PIXMAP,
417
32, PropModeReplace, (guchar *) &pixmap_as_long,
422
XFreeGC (slave->priv->server_display, gc);
426
gdm_slave_save_root_windows (GdmSlave *slave)
428
int i, number_of_screens;
431
number_of_screens = ScreenCount (slave->priv->server_display);
433
atom = XInternAtom (slave->priv->server_display,
434
"_XROOTPMAP_ID", False);
440
for (i = 0; i < number_of_screens; i++) {
441
gdm_slave_save_root_window_of_screen (slave, atom, i);
444
XSync (slave->priv->server_display, False);
448
determine_initial_cursor_position (GdmSlave *slave,
452
XRRScreenResources *resources;
453
RROutput primary_output;
456
/* If this function fails for whatever reason,
457
* put the pointer in the upper left corner of the
463
gdm_error_trap_push ();
464
resources = XRRGetScreenResources (slave->priv->server_display,
465
DefaultRootWindow (slave->priv->server_display));
466
primary_output = XRRGetOutputPrimary (slave->priv->server_display,
467
DefaultRootWindow (slave->priv->server_display));
468
gdm_error_trap_pop ();
470
if (resources == NULL) {
474
for (i = 0; i < resources->noutput; i++) {
475
XRROutputInfo *output_info;
477
if (primary_output == None) {
478
primary_output = resources->outputs[0];
481
if (resources->outputs[i] != primary_output) {
485
output_info = XRRGetOutputInfo (slave->priv->server_display,
487
resources->outputs[i]);
489
if (output_info->connection != RR_Disconnected &&
490
output_info->crtc != 0) {
491
XRRCrtcInfo *crtc_info;
493
crtc_info = XRRGetCrtcInfo (slave->priv->server_display,
496
/* position it sort of in the lower right
498
*x = crtc_info->x + .9 * crtc_info->width;
499
*y = crtc_info->y + .9 * crtc_info->height;
500
XRRFreeCrtcInfo (crtc_info);
503
XRRFreeOutputInfo (output_info);
507
XRRFreeScreenResources (resources);
511
gdm_slave_set_initial_cursor_position (GdmSlave *slave)
513
if (slave->priv->server_display != NULL) {
516
determine_initial_cursor_position (slave, &x, &y);
517
XWarpPointer(slave->priv->server_display,
519
DefaultRootWindow (slave->priv->server_display),
527
gdm_slave_set_busy_cursor (GdmSlave *slave)
529
if (slave->priv->server_display != NULL) {
532
xcursor = XCreateFontCursor (slave->priv->server_display, CURSOR_WATCH);
533
XDefineCursor (slave->priv->server_display,
534
DefaultRootWindow (slave->priv->server_display),
536
XFreeCursor (slave->priv->server_display, xcursor);
537
XSync (slave->priv->server_display, False);
542
gdm_slave_setup_xhost_auth (XHostAddress *host_entries, XServerInterpretedAddress *si_entries)
544
si_entries[0].type = "localuser";
545
si_entries[0].typelength = strlen ("localuser");
546
si_entries[1].type = "localuser";
547
si_entries[1].typelength = strlen ("localuser");
548
si_entries[2].type = "localuser";
549
si_entries[2].typelength = strlen ("localuser");
551
si_entries[0].value = "root";
552
si_entries[0].valuelength = strlen ("root");
553
si_entries[1].value = GDM_USERNAME;
554
si_entries[1].valuelength = strlen (GDM_USERNAME);
555
si_entries[2].value = "gnome-initial-setup";
556
si_entries[2].valuelength = strlen ("gnome-initial-setup");
558
host_entries[0].family = FamilyServerInterpreted;
559
host_entries[0].address = (char *) &si_entries[0];
560
host_entries[0].length = sizeof (XServerInterpretedAddress);
561
host_entries[1].family = FamilyServerInterpreted;
562
host_entries[1].address = (char *) &si_entries[1];
563
host_entries[1].length = sizeof (XServerInterpretedAddress);
564
host_entries[2].family = FamilyServerInterpreted;
565
host_entries[2].address = (char *) &si_entries[2];
566
host_entries[2].length = sizeof (XServerInterpretedAddress);
570
gdm_slave_set_windowpath (GdmSlave *slave)
572
/* setting WINDOWPATH for clients */
576
unsigned long nitems;
577
unsigned long bytes_after;
579
const char *windowpath;
585
prop = XInternAtom (slave->priv->server_display, "XFree86_VT", False);
587
g_debug ("no XFree86_VT atom\n");
590
if (XGetWindowProperty (slave->priv->server_display,
591
DefaultRootWindow (slave->priv->server_display), prop, 0, 1,
592
False, AnyPropertyType, &actualtype, &actualformat,
593
&nitems, &bytes_after, &buf)) {
594
g_debug ("no XFree86_VT property\n");
599
g_debug ("%lu items in XFree86_VT property!\n", nitems);
604
switch (actualtype) {
608
switch (actualformat) {
610
num = (*(uint8_t *)(void *)buf);
613
num = (*(uint16_t *)(void *)buf);
616
num = (*(long *)(void *)buf);
619
g_debug ("format %d in XFree86_VT property!\n", actualformat);
625
g_debug ("type %lx in XFree86_VT property!\n", actualtype);
631
windowpath = getenv ("WINDOWPATH");
632
numn = snprintf (nums, sizeof (nums), "%lu", num);
634
newwindowpath = malloc (numn + 1);
635
sprintf (newwindowpath, "%s", nums);
637
newwindowpath = malloc (strlen (windowpath) + 1 + numn + 1);
638
sprintf (newwindowpath, "%s:%s", windowpath, nums);
641
slave->priv->windowpath = newwindowpath;
643
g_setenv ("WINDOWPATH", newwindowpath, TRUE);
647
gdm_slave_connect_to_x11_display (GdmSlave *slave)
655
/* We keep our own (windowless) connection (dsp) open to avoid the
656
* X server resetting due to lack of active connections. */
658
g_debug ("GdmSlave: Server is ready - opening display %s", slave->priv->display_name);
660
g_setenv ("DISPLAY", slave->priv->display_name, TRUE);
661
g_setenv ("XAUTHORITY", slave->priv->display_x11_authority_file, TRUE);
664
sigaddset (&mask, SIGCHLD);
665
sigprocmask (SIG_BLOCK, &mask, &omask);
667
/* Give slave access to the display independent of current hostname */
668
XSetAuthorization ("MIT-MAGIC-COOKIE-1",
669
strlen ("MIT-MAGIC-COOKIE-1"),
670
slave->priv->display_x11_cookie,
671
strlen (slave->priv->display_x11_cookie));
673
slave->priv->server_display = XOpenDisplay (slave->priv->display_name);
675
sigprocmask (SIG_SETMASK, &omask, NULL);
678
if (slave->priv->server_display == NULL) {
679
g_warning ("Unable to connect to display %s", slave->priv->display_name);
681
} else if (slave->priv->display_is_local) {
682
XServerInterpretedAddress si_entries[3];
683
XHostAddress host_entries[3];
685
g_debug ("GdmSlave: Connected to display %s", slave->priv->display_name);
688
/* Give programs run by the slave and greeter access to the
689
* display independent of current hostname
691
gdm_slave_setup_xhost_auth (host_entries, si_entries);
693
gdm_error_trap_push ();
694
XAddHosts (slave->priv->server_display, host_entries,
695
G_N_ELEMENTS (host_entries));
696
XSync (slave->priv->server_display, False);
697
if (gdm_error_trap_pop ()) {
698
g_warning ("Failed to give slave programs access to the display. Trying to proceed.");
701
gdm_slave_set_windowpath (slave);
703
g_debug ("GdmSlave: Connected to display %s", slave->priv->display_name);
711
gdm_slave_set_slave_bus_name (GdmSlave *slave)
717
name = g_dbus_connection_get_unique_name (slave->priv->connection);
720
res = gdm_dbus_display_call_set_slave_bus_name_sync (slave->priv->display_proxy,
725
g_warning ("Failed to set slave bus name on parent: %s", error->message);
726
g_error_free (error);
733
gdm_slave_real_start (GdmSlave *slave)
739
g_debug ("GdmSlave: Starting slave");
741
g_assert (slave->priv->display_proxy == NULL);
743
g_debug ("GdmSlave: Creating proxy for %s", slave->priv->display_id);
745
slave->priv->display_proxy = GDM_DBUS_DISPLAY (gdm_dbus_display_proxy_new_sync (slave->priv->connection,
746
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
748
slave->priv->display_id,
752
if (slave->priv->display_proxy == NULL) {
753
g_warning ("Failed to create display proxy %s: %s", slave->priv->display_id, error->message);
754
g_error_free (error);
759
res = gdm_dbus_display_call_get_id_sync (slave->priv->display_proxy,
764
g_warning ("Failed to get display ID %s: %s", slave->priv->display_id, error->message);
765
g_error_free (error);
769
g_debug ("GdmSlave: Got display ID: %s", id);
771
if (strcmp (id, slave->priv->display_id) != 0) {
772
g_critical ("Display ID doesn't match");
776
gdm_slave_set_slave_bus_name (slave);
778
/* cache some values up front */
780
res = gdm_dbus_display_call_is_local_sync (slave->priv->display_proxy,
781
&slave->priv->display_is_local,
785
g_warning ("Failed to get value: %s", error->message);
786
g_error_free (error);
791
res = gdm_dbus_display_call_get_x11_display_name_sync (slave->priv->display_proxy,
792
&slave->priv->display_name,
796
g_warning ("Failed to get value: %s", error->message);
797
g_error_free (error);
802
res = gdm_dbus_display_call_get_x11_display_number_sync (slave->priv->display_proxy,
803
&slave->priv->display_number,
807
g_warning ("Failed to get value: %s", error->message);
808
g_error_free (error);
813
res = gdm_dbus_display_call_get_remote_hostname_sync (slave->priv->display_proxy,
814
&slave->priv->display_hostname,
818
g_warning ("Failed to get value: %s", error->message);
819
g_error_free (error);
824
res = gdm_dbus_display_call_get_x11_cookie_sync (slave->priv->display_proxy,
825
&slave->priv->display_x11_cookie,
829
g_warning ("Failed to get value: %s", error->message);
830
g_error_free (error);
835
res = gdm_dbus_display_call_get_x11_authority_file_sync (slave->priv->display_proxy,
836
&slave->priv->display_x11_authority_file,
840
g_warning ("Failed to get value: %s", error->message);
841
g_error_free (error);
846
res = gdm_dbus_display_call_get_seat_id_sync (slave->priv->display_proxy,
847
&slave->priv->display_seat_id,
851
g_warning ("Failed to get value: %s", error->message);
852
g_error_free (error);
857
res = gdm_dbus_display_call_is_initial_sync (slave->priv->display_proxy,
858
&slave->priv->display_is_initial,
862
g_warning ("Failed to get value: %s", error->message);
863
g_error_free (error);
871
gdm_slave_real_stop (GdmSlave *slave)
873
g_debug ("GdmSlave: Stopping slave");
875
g_clear_object (&slave->priv->display_proxy);
881
gdm_slave_start (GdmSlave *slave)
885
g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE);
887
g_debug ("GdmSlave: starting slave");
889
g_object_ref (slave);
890
ret = GDM_SLAVE_GET_CLASS (slave)->start (slave);
891
g_object_unref (slave);
897
gdm_slave_stop (GdmSlave *slave)
901
g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE);
903
g_debug ("GdmSlave: stopping slave");
905
g_object_ref (slave);
907
ret = GDM_SLAVE_GET_CLASS (slave)->stop (slave);
908
g_signal_emit (slave, signals [STOPPED], 0);
910
g_object_unref (slave);
915
gdm_slave_add_user_authorization (GdmSlave *slave,
916
const char *username,
919
XServerInterpretedAddress si_entries[3];
920
XHostAddress host_entries[3];
927
if (filenamep != NULL) {
931
g_debug ("GdmSlave: Requesting user authorization");
934
res = gdm_dbus_display_call_add_user_authorization_sync (slave->priv->display_proxy,
941
g_warning ("Failed to add user authorization: %s", error->message);
942
g_error_free (error);
944
g_debug ("GdmSlave: Got user authorization: %s", filename);
947
if (filenamep != NULL) {
948
*filenamep = g_strdup (filename);
952
/* Remove access for the programs run by slave and greeter now that the
953
* user session is starting.
955
gdm_slave_setup_xhost_auth (host_entries, si_entries);
956
gdm_error_trap_push ();
957
XRemoveHosts (slave->priv->server_display, host_entries,
958
G_N_ELEMENTS (host_entries));
959
XSync (slave->priv->server_display, False);
960
if (gdm_error_trap_pop ()) {
961
g_warning ("Failed to remove slave program access to the display. Trying to proceed.");
969
gdm_slave_parse_enriched_login (GdmSlave *slave,
970
const char *username,
971
const char *display_name)
978
char *parsed_username;
983
parsed_username = NULL;
985
if (username == NULL || username[0] == '\0') {
989
/* A script may be used to generate the automatic/timed login name
990
based on the display/host by ending the name with the pipe symbol
993
username_len = strlen (username);
994
if (username[username_len - 1] != '|') {
995
return g_strdup (username);
998
/* Remove the pipe symbol */
999
command = g_strndup (username, username_len - 1);
1003
if (! g_shell_parse_argv (command, NULL, &argv, &error)) {
1004
g_warning ("GdmSlave: Could not parse command '%s': %s", command, error->message);
1005
g_error_free (error);
1011
g_debug ("GdmSlave: running '%s' to acquire auto/timed username", command);
1014
env = get_script_environment (slave, NULL);
1019
res = g_spawn_sync (NULL,
1021
(char **)env->pdata,
1022
G_SPAWN_SEARCH_PATH,
1030
g_ptr_array_foreach (env, (GFunc)g_free, NULL);
1031
g_ptr_array_free (env, TRUE);
1035
g_warning ("GdmSlave: Unable to launch auto/timed login script '%s': %s", username, error->message);
1036
g_error_free (error);
1038
g_free (std_output);
1043
if (std_output != NULL) {
1044
g_strchomp (std_output);
1045
if (std_output[0] != '\0') {
1046
parsed_username = g_strdup (std_output);
1052
return parsed_username;
1056
gdm_slave_get_timed_login_details (GdmSlave *slave,
1061
struct passwd *pwent;
1072
g_debug ("GdmSlave: Requesting timed login details");
1075
res = gdm_dbus_display_call_get_timed_login_details_sync (slave->priv->display_proxy,
1082
g_warning ("Failed to get timed login details: %s", error->message);
1083
g_error_free (error);
1085
g_debug ("GdmSlave: Got timed login details: %d %s %d", enabled, username, delay);
1088
if (usernamep != NULL) {
1089
*usernamep = gdm_slave_parse_enriched_login (slave,
1091
slave->priv->display_name);
1095
if (enabledp != NULL) {
1096
*enabledp = enabled;
1098
if (delayp != NULL) {
1105
if (usernamep != NULL && *usernamep != NULL) {
1106
gdm_get_pwent_for_name (*usernamep, &pwent);
1107
if (pwent == NULL) {
1108
g_debug ("Invalid username %s for auto/timed login",
1110
g_free (*usernamep);
1113
g_debug ("Using username %s for auto/timed login",
1116
if (enabledp != NULL) {
1117
*enabledp = enabled;
1119
if (delayp != NULL) {
1124
g_debug ("Invalid NULL username for auto/timed login");
1131
_get_uid_and_gid_for_user (const char *username,
1135
struct passwd *passwd_entry;
1137
g_assert (username != NULL);
1140
gdm_get_pwent_for_name (username, &passwd_entry);
1142
if (passwd_entry == NULL) {
1147
*uid = passwd_entry->pw_uid;
1151
*gid = passwd_entry->pw_gid;
1157
#ifdef WITH_CONSOLE_KIT
1160
x11_session_is_on_seat (GdmSlave *slave,
1161
const char *session_id,
1162
const char *seat_id)
1164
GError *error = NULL;
1168
char *x11_display_device;
1174
x11_display_device = NULL;
1176
if (seat_id == NULL || seat_id[0] == '\0' || session_id == NULL || session_id[0] == '\0') {
1180
reply = g_dbus_connection_call_sync (slave->priv->connection,
1183
CK_SESSION_INTERFACE,
1185
NULL, /* parameters */
1186
G_VARIANT_TYPE ("(o)"),
1187
G_DBUS_CALL_FLAGS_NONE,
1191
if (reply == NULL) {
1192
g_debug ("Failed to identify the current seat: %s", error->message);
1193
g_error_free (error);
1197
g_variant_get (reply, "(o)", &sid);
1198
g_variant_unref (reply);
1200
if (sid == NULL || sid[0] == '\0' || strcmp (sid, seat_id) != 0) {
1201
g_debug ("GdmSlave: session not on current seat: %s", seat_id);
1205
reply = g_dbus_connection_call_sync (slave->priv->connection,
1208
CK_SESSION_INTERFACE,
1210
NULL, /* parameters */
1211
G_VARIANT_TYPE ("(s)"),
1212
G_DBUS_CALL_FLAGS_NONE,
1216
if (reply == NULL) {
1217
g_error_free (error);
1221
g_variant_get (reply, "(s)", &x11_display);
1222
g_variant_unref (reply);
1224
/* ignore tty sessions */
1225
if (x11_display == NULL || x11_display[0] == '\0') {
1229
reply = g_dbus_connection_call_sync (slave->priv->connection,
1232
CK_SESSION_INTERFACE,
1233
"GetX11DisplayDevice",
1234
NULL, /* parameters */
1235
G_VARIANT_TYPE ("(s)"),
1236
G_DBUS_CALL_FLAGS_NONE,
1240
if (reply == NULL) {
1241
g_error_free (error);
1245
g_variant_get (reply, "(s)", &x11_display_device);
1246
g_variant_unref (reply);
1248
if (x11_display_device == NULL || x11_display_device[0] == '\0') {
1254
g_free (x11_display_device);
1255
g_free (x11_display);
1265
gdm_slave_get_primary_session_id_for_user_from_systemd (GdmSlave *slave,
1266
const char *username)
1272
gboolean got_primary_ssid;
1274
primary_ssid = NULL;
1275
got_primary_ssid = FALSE;
1277
res = sd_seat_can_multi_session (slave->priv->display_seat_id);
1279
g_warning ("GdmSlave: Failed to determine whether seat is multi-session capable: %s", strerror (-res));
1281
} else if (res == 0) {
1282
g_debug ("GdmSlave: seat is unable to activate sessions");
1286
if (! _get_uid_and_gid_for_user (username, &uid, NULL)) {
1287
g_debug ("GdmSlave: unable to determine uid for user: %s", username);
1291
res = sd_seat_get_sessions (slave->priv->display_seat_id, &sessions, NULL, NULL);
1293
g_warning ("GdmSlave: Failed to get sessions on seat: %s", strerror (-res));
1297
if (sessions == NULL) {
1298
g_debug ("GdmSlave: seat has no active sessions");
1302
for (i = 0; sessions[i] != NULL; i++) {
1305
gboolean is_closing;
1310
res = sd_session_get_type (sessions[i], &type);
1313
g_warning ("GdmSlave: could not fetch type of session '%s': %s",
1314
sessions[i], strerror (-res));
1318
is_x11 = g_strcmp0 (type, "x11") == 0;
1321
/* Only migrate to graphical sessions
1327
/* Always give preference to non-active sessions,
1328
* so we migrate when we can and don't when we can't
1330
res = sd_session_get_state (sessions[i], &state);
1332
g_warning ("GdmSlave: could not fetch state of session '%s': %s",
1333
sessions[i], strerror (-res));
1337
is_closing = g_strcmp0 (state, "closing") == 0;
1338
is_active = g_strcmp0 (state, "active") == 0;
1341
/* Ignore closing sessions
1347
res = sd_session_get_uid (sessions[i], &other);
1348
if (res == 0 && other == uid && !got_primary_ssid) {
1349
g_free (primary_ssid);
1350
primary_ssid = g_strdup (sessions[i]);
1353
got_primary_ssid = TRUE;
1360
return primary_ssid;
1364
#ifdef WITH_CONSOLE_KIT
1366
gdm_slave_get_primary_session_id_for_user_from_ck (GdmSlave *slave,
1367
const char *username)
1369
gboolean can_activate_sessions;
1371
const char **sessions;
1378
primary_ssid = NULL;
1380
g_debug ("GdmSlave: getting proxy for seat: %s", slave->priv->display_seat_id);
1381
g_debug ("GdmSlave: checking if seat can activate sessions");
1383
reply = g_dbus_connection_call_sync (slave->priv->connection,
1385
slave->priv->display_seat_id,
1387
"CanActivateSessions",
1388
NULL, /* parameters */
1389
G_VARIANT_TYPE ("(b)"),
1390
G_DBUS_CALL_FLAGS_NONE,
1394
if (reply == NULL) {
1395
g_warning ("unable to determine if seat can activate sessions: %s", error->message);
1396
g_error_free (error);
1400
g_variant_get (reply, "(b)", &can_activate_sessions);
1401
g_variant_unref (reply);
1403
if (! can_activate_sessions) {
1404
g_debug ("GdmSlave: seat is unable to activate sessions");
1408
if (! _get_uid_and_gid_for_user (username, &uid, NULL)) {
1409
g_debug ("GdmSlave: unable to determine uid for user: %s", username);
1413
reply = g_dbus_connection_call_sync (slave->priv->connection,
1416
CK_MANAGER_INTERFACE,
1417
"GetSessionsForUnixUser",
1418
g_variant_new ("(u)", uid),
1419
G_VARIANT_TYPE ("(ao)"),
1420
G_DBUS_CALL_FLAGS_NONE,
1425
if (reply == NULL) {
1426
g_warning ("unable to determine sessions for user: %s", error->message);
1427
g_error_free (error);
1431
g_variant_get_child (reply, 0, "^a&o", &sessions);
1432
for (i = 0; sessions[i] != NULL; i++) {
1433
if (x11_session_is_on_seat (slave, sessions[i], slave->priv->display_seat_id)) {
1434
primary_ssid = g_strdup (sessions[i]);
1440
g_variant_unref (reply);
1441
return primary_ssid;
1446
gdm_slave_get_primary_session_id_for_user (GdmSlave *slave,
1447
const char *username)
1450
if (slave->priv->display_seat_id == NULL || slave->priv->display_seat_id[0] == '\0') {
1451
g_debug ("GdmSlave: display seat ID is not set; can't switch sessions");
1456
if (sd_booted () > 0) {
1457
return gdm_slave_get_primary_session_id_for_user_from_systemd (slave, username);
1461
#ifdef WITH_CONSOLE_KIT
1462
return gdm_slave_get_primary_session_id_for_user_from_ck (slave, username);
1470
activate_session_id_for_systemd (GdmSlave *slave,
1471
const char *seat_id,
1472
const char *session_id)
1474
GError *error = NULL;
1477
reply = g_dbus_connection_call_sync (slave->priv->connection,
1478
"org.freedesktop.login1",
1479
"/org/freedesktop/login1",
1480
"org.freedesktop.login1.Manager",
1481
"ActivateSessionOnSeat",
1482
g_variant_new ("(ss)", session_id, seat_id),
1483
NULL, /* expected reply */
1484
G_DBUS_CALL_FLAGS_NONE,
1488
if (reply == NULL) {
1489
g_debug ("GdmSlave: logind 'ActivateSessionOnSeat' %s raised:\n %s\n\n",
1490
g_dbus_error_get_remote_error (error), error->message);
1491
g_error_free (error);
1495
g_variant_unref (reply);
1501
#ifdef WITH_CONSOLE_KIT
1503
activate_session_id_for_ck (GdmSlave *slave,
1504
const char *seat_id,
1505
const char *session_id)
1507
GError *error = NULL;
1510
reply = g_dbus_connection_call_sync (slave->priv->connection,
1513
"org.freedesktop.ConsoleKit.Seat",
1515
g_variant_new ("(o)", session_id),
1516
NULL, /* expected reply */
1517
G_DBUS_CALL_FLAGS_NONE,
1521
if (reply == NULL) {
1522
g_debug ("GdmSlave: ConsoleKit %s raised:\n %s\n\n",
1523
g_dbus_error_get_remote_error (error), error->message);
1524
g_error_free (error);
1528
g_variant_unref (reply);
1535
activate_session_id (GdmSlave *slave,
1536
const char *seat_id,
1537
const char *session_id)
1541
if (sd_booted () > 0) {
1542
return activate_session_id_for_systemd (slave, seat_id, session_id);
1546
#ifdef WITH_CONSOLE_KIT
1547
return activate_session_id_for_ck (slave, seat_id, session_id);
1553
#ifdef WITH_CONSOLE_KIT
1555
ck_session_is_active (GdmSlave *slave,
1556
const char *seat_id,
1557
const char *session_id)
1559
GError *error = NULL;
1563
reply = g_dbus_connection_call_sync (slave->priv->connection,
1566
"org.freedesktop.ConsoleKit.Session",
1569
G_VARIANT_TYPE ("(b)"),
1570
G_DBUS_CALL_FLAGS_NONE,
1574
if (reply == NULL) {
1575
g_debug ("GdmSlave: ConsoleKit IsActive %s raised:\n %s\n\n",
1576
g_dbus_error_get_remote_error (error), error->message);
1577
g_error_free (error);
1581
g_variant_get (reply, "(b)", &is_active);
1582
g_variant_unref (reply);
1589
session_is_active (GdmSlave *slave,
1590
const char *seat_id,
1591
const char *session_id)
1594
if (sd_booted () > 0) {
1595
return sd_session_is_active (session_id) > 0;
1599
#ifdef WITH_CONSOLE_KIT
1600
return ck_session_is_active (slave, seat_id, session_id);
1608
session_unlock_for_systemd (GdmSlave *slave,
1611
GError *error = NULL;
1614
reply = g_dbus_connection_call_sync (slave->priv->connection,
1615
"org.freedesktop.login1",
1616
"/org/freedesktop/login1",
1617
"org.freedesktop.login1.Manager",
1619
g_variant_new ("(s)", ssid),
1620
NULL, /* expected reply */
1621
G_DBUS_CALL_FLAGS_NONE,
1625
if (reply == NULL) {
1626
g_debug ("GdmSlave: logind 'UnlockSession' %s raised:\n %s\n\n",
1627
g_dbus_error_get_remote_error (error), error->message);
1628
g_error_free (error);
1632
g_variant_unref (reply);
1638
#ifdef WITH_CONSOLE_KIT
1640
session_unlock_for_ck (GdmSlave *slave,
1643
GError *error = NULL;
1646
reply = g_dbus_connection_call_sync (slave->priv->connection,
1649
CK_SESSION_INTERFACE,
1651
NULL, /* parameters */
1652
NULL, /* expected reply */
1653
G_DBUS_CALL_FLAGS_NONE,
1657
if (reply == NULL) {
1658
g_debug ("GdmSlave: ConsoleKit %s raised:\n %s\n\n",
1659
g_dbus_error_get_remote_error (error), error->message);
1660
g_error_free (error);
1664
g_variant_unref (reply);
1671
session_unlock (GdmSlave *slave,
1675
g_debug ("Unlocking session %s", ssid);
1678
if (sd_booted () > 0) {
1679
return session_unlock_for_systemd (slave, ssid);
1683
#ifdef WITH_CONSOLE_KIT
1684
return session_unlock_for_ck (slave, ssid);
1691
gdm_slave_switch_to_user_session (GdmSlave *slave,
1692
const char *username,
1693
gboolean fail_if_already_switched)
1697
gboolean session_already_switched;
1698
char *ssid_to_activate;
1702
ssid_to_activate = gdm_slave_get_primary_session_id_for_user (slave, username);
1703
if (ssid_to_activate == NULL) {
1704
g_debug ("GdmSlave: unable to determine session to activate");
1708
session_already_switched = session_is_active (slave, slave->priv->display_seat_id, ssid_to_activate);
1710
g_debug ("GdmSlave: Activating session: '%s'", ssid_to_activate);
1712
if (session_already_switched && fail_if_already_switched) {
1713
g_debug ("GdmSlave: unable to activate session since it's already active: %s", ssid_to_activate);
1717
if (!session_already_switched) {
1718
res = activate_session_id (slave, slave->priv->display_seat_id, ssid_to_activate);
1720
g_debug ("GdmSlave: unable to activate session: %s", ssid_to_activate);
1725
res = session_unlock (slave, ssid_to_activate);
1727
/* this isn't fatal */
1728
g_debug ("GdmSlave: unable to unlock session: %s", ssid_to_activate);
1734
g_free (ssid_to_activate);
1740
_gdm_slave_set_session_id (GdmSlave *slave,
1743
g_free (slave->priv->session_id);
1744
slave->priv->session_id = g_strdup (id);
1748
_gdm_slave_set_display_id (GdmSlave *slave,
1751
g_free (slave->priv->display_id);
1752
slave->priv->display_id = g_strdup (id);
1756
_gdm_slave_set_display_name (GdmSlave *slave,
1759
g_free (slave->priv->display_name);
1760
slave->priv->display_name = g_strdup (name);
1764
_gdm_slave_set_display_number (GdmSlave *slave,
1767
slave->priv->display_number = number;
1771
_gdm_slave_set_display_hostname (GdmSlave *slave,
1774
g_free (slave->priv->display_hostname);
1775
slave->priv->display_hostname = g_strdup (name);
1779
_gdm_slave_set_display_x11_authority_file (GdmSlave *slave,
1782
g_free (slave->priv->display_x11_authority_file);
1783
slave->priv->display_x11_authority_file = g_strdup (name);
1787
_gdm_slave_set_display_seat_id (GdmSlave *slave,
1790
g_free (slave->priv->display_seat_id);
1791
slave->priv->display_seat_id = g_strdup (id);
1795
_gdm_slave_set_display_is_local (GdmSlave *slave,
1798
slave->priv->display_is_local = is;
1802
_gdm_slave_set_display_is_initial (GdmSlave *slave,
1805
slave->priv->display_is_initial = is;
1809
gdm_slave_set_property (GObject *object,
1811
const GValue *value,
1816
self = GDM_SLAVE (object);
1819
case PROP_SESSION_ID:
1820
_gdm_slave_set_session_id (self, g_value_get_string (value));
1822
case PROP_DISPLAY_ID:
1823
_gdm_slave_set_display_id (self, g_value_get_string (value));
1825
case PROP_DISPLAY_NAME:
1826
_gdm_slave_set_display_name (self, g_value_get_string (value));
1828
case PROP_DISPLAY_NUMBER:
1829
_gdm_slave_set_display_number (self, g_value_get_int (value));
1831
case PROP_DISPLAY_HOSTNAME:
1832
_gdm_slave_set_display_hostname (self, g_value_get_string (value));
1834
case PROP_DISPLAY_SEAT_ID:
1835
_gdm_slave_set_display_seat_id (self, g_value_get_string (value));
1837
case PROP_DISPLAY_X11_AUTHORITY_FILE:
1838
_gdm_slave_set_display_x11_authority_file (self, g_value_get_string (value));
1840
case PROP_DISPLAY_IS_LOCAL:
1841
_gdm_slave_set_display_is_local (self, g_value_get_boolean (value));
1843
case PROP_DISPLAY_IS_INITIAL:
1844
_gdm_slave_set_display_is_initial (self, g_value_get_boolean (value));
1847
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1853
gdm_slave_get_property (GObject *object,
1860
self = GDM_SLAVE (object);
1863
case PROP_SESSION_ID:
1864
g_value_set_string (value, self->priv->session_id);
1866
case PROP_DISPLAY_ID:
1867
g_value_set_string (value, self->priv->display_id);
1869
case PROP_DISPLAY_NAME:
1870
g_value_set_string (value, self->priv->display_name);
1872
case PROP_DISPLAY_NUMBER:
1873
g_value_set_int (value, self->priv->display_number);
1875
case PROP_DISPLAY_HOSTNAME:
1876
g_value_set_string (value, self->priv->display_hostname);
1878
case PROP_DISPLAY_SEAT_ID:
1879
g_value_set_string (value, self->priv->display_seat_id);
1881
case PROP_DISPLAY_X11_AUTHORITY_FILE:
1882
g_value_set_string (value, self->priv->display_x11_authority_file);
1884
case PROP_DISPLAY_IS_LOCAL:
1885
g_value_set_boolean (value, self->priv->display_is_local);
1887
case PROP_DISPLAY_IS_INITIAL:
1888
g_value_set_boolean (value, self->priv->display_is_initial);
1891
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1897
handle_open_session (GdmDBusSlave *skeleton,
1898
GDBusMethodInvocation *invocation,
1904
GdmSlaveClass *slave_class;
1907
slave_class = GDM_SLAVE_GET_CLASS (slave);
1908
if (slave_class->open_session == NULL) {
1909
g_dbus_method_invocation_return_dbus_error (invocation,
1910
"org.gnome.DisplayManager.Slave.Unsupported",
1911
"Connections to the slave are not supported by this slave");
1917
if (!slave_class->open_session (slave,
1918
(GPid) pid_of_caller,
1919
(uid_t) uid_of_caller,
1922
g_dbus_method_invocation_return_gerror (invocation, error);
1923
g_error_free (error);
1927
gdm_dbus_slave_complete_open_session (skeleton, invocation, address);
1934
on_reauthentication_channel_opened (GdmSlave *slave,
1935
GAsyncResult *result,
1936
GDBusMethodInvocation *invocation)
1938
GdmSlaveClass *slave_class;
1942
slave_class = GDM_SLAVE_GET_CLASS (slave);
1944
g_assert (slave_class->open_reauthentication_channel_finish != NULL);
1947
address = slave_class->open_reauthentication_channel_finish (slave, result, &error);
1949
if (address == NULL) {
1950
g_dbus_method_invocation_return_gerror (invocation, error);
1952
gdm_dbus_slave_complete_open_reauthentication_channel (slave->priv->skeleton,
1957
g_object_unref (invocation);
1961
handle_open_reauthentication_channel (GdmDBusSlave *skeleton,
1962
GDBusMethodInvocation *invocation,
1963
const char *username,
1965
uid_t uid_of_caller,
1968
GdmSlaveClass *slave_class;
1970
slave_class = GDM_SLAVE_GET_CLASS (slave);
1971
if (slave_class->open_reauthentication_channel == NULL) {
1972
g_dbus_method_invocation_return_dbus_error (invocation,
1973
"org.gnome.DisplayManager.Slave.Unsupported",
1974
"Connections to the slave are not supported by this slave");
1978
slave_class->open_reauthentication_channel (slave,
1982
(GAsyncReadyCallback)
1983
on_reauthentication_channel_opened,
1984
g_object_ref (invocation),
1991
register_slave (GdmSlave *slave)
1996
slave->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM,
1999
if (slave->priv->connection == NULL) {
2000
g_critical ("error getting system bus: %s", error->message);
2001
g_error_free (error);
2005
slave->priv->skeleton = GDM_DBUS_SLAVE (gdm_dbus_slave_skeleton_new ());
2007
g_signal_connect (slave->priv->skeleton,
2008
"handle-open-session",
2009
G_CALLBACK (handle_open_session),
2011
g_signal_connect (slave->priv->skeleton,
2012
"handle-open-reauthentication-channel",
2013
G_CALLBACK (handle_open_reauthentication_channel),
2016
g_object_bind_property (G_OBJECT (slave),
2018
G_OBJECT (slave->priv->skeleton),
2022
gdm_slave_export_interface (slave,
2023
G_DBUS_INTERFACE_SKELETON (slave->priv->skeleton));
2029
gdm_slave_constructor (GType type,
2030
guint n_construct_properties,
2031
GObjectConstructParam *construct_properties)
2036
slave = GDM_SLAVE (G_OBJECT_CLASS (gdm_slave_parent_class)->constructor (type,
2037
n_construct_properties,
2038
construct_properties));
2039
g_debug ("GdmSlave: Registering");
2041
res = register_slave (slave);
2043
g_warning ("Unable to register slave with system bus");
2046
return G_OBJECT (slave);
2050
gdm_slave_class_init (GdmSlaveClass *klass)
2052
GObjectClass *object_class = G_OBJECT_CLASS (klass);
2054
object_class->get_property = gdm_slave_get_property;
2055
object_class->set_property = gdm_slave_set_property;
2056
object_class->constructor = gdm_slave_constructor;
2057
object_class->finalize = gdm_slave_finalize;
2059
klass->start = gdm_slave_real_start;
2060
klass->stop = gdm_slave_real_stop;
2062
g_type_class_add_private (klass, sizeof (GdmSlavePrivate));
2064
g_object_class_install_property (object_class,
2066
g_param_spec_string ("session-id",
2070
G_PARAM_READWRITE));
2071
g_object_class_install_property (object_class,
2073
g_param_spec_string ("display-id",
2077
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2078
g_object_class_install_property (object_class,
2080
g_param_spec_string ("display-name",
2084
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2085
g_object_class_install_property (object_class,
2086
PROP_DISPLAY_NUMBER,
2087
g_param_spec_int ("display-number",
2093
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2094
g_object_class_install_property (object_class,
2095
PROP_DISPLAY_HOSTNAME,
2096
g_param_spec_string ("display-hostname",
2100
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2101
g_object_class_install_property (object_class,
2102
PROP_DISPLAY_SEAT_ID,
2103
g_param_spec_string ("display-seat-id",
2107
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2108
g_object_class_install_property (object_class,
2109
PROP_DISPLAY_X11_AUTHORITY_FILE,
2110
g_param_spec_string ("display-x11-authority-file",
2114
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2115
g_object_class_install_property (object_class,
2116
PROP_DISPLAY_IS_LOCAL,
2117
g_param_spec_boolean ("display-is-local",
2121
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2122
g_object_class_install_property (object_class,
2123
PROP_DISPLAY_IS_INITIAL,
2124
g_param_spec_boolean ("display-is-initial",
2128
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2131
g_signal_new ("stopped",
2132
G_TYPE_FROM_CLASS (object_class),
2134
G_STRUCT_OFFSET (GdmSlaveClass, stopped),
2137
g_cclosure_marshal_VOID__VOID,
2143
gdm_slave_init (GdmSlave *slave)
2146
slave->priv = GDM_SLAVE_GET_PRIVATE (slave);
2148
slave->priv->pid = -1;
2152
gdm_slave_finalize (GObject *object)
2156
g_return_if_fail (object != NULL);
2157
g_return_if_fail (GDM_IS_SLAVE (object));
2159
slave = GDM_SLAVE (object);
2161
g_return_if_fail (slave->priv != NULL);
2163
gdm_slave_real_stop (slave);
2165
g_free (slave->priv->display_id);
2166
g_free (slave->priv->display_name);
2167
g_free (slave->priv->display_hostname);
2168
g_free (slave->priv->display_seat_id);
2169
g_free (slave->priv->display_x11_authority_file);
2170
g_free (slave->priv->parent_display_name);
2171
g_free (slave->priv->parent_display_x11_authority_file);
2172
g_free (slave->priv->windowpath);
2173
g_free (slave->priv->display_x11_cookie);
2175
G_OBJECT_CLASS (gdm_slave_parent_class)->finalize (object);
2179
gdm_slave_export_interface (GdmSlave *slave,
2180
GDBusInterfaceSkeleton *interface)
2182
g_dbus_interface_skeleton_export (interface,
2183
slave->priv->connection,