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.
28
#include <sys/types.h>
32
#ifdef HAVE_LOGINDEVPERM
33
#include <libdevinfo.h>
34
#endif /* HAVE_LOGINDEVPERM */
37
#include <glib/gi18n.h>
38
#include <glib/gstdio.h>
39
#include <glib-object.h>
41
#include <X11/Xlib.h> /* for Display */
43
#include <act/act-user-manager.h>
45
#include "gdm-common.h"
47
#include "gdm-settings-client.h"
48
#include "gdm-settings-keys.h"
50
#include "gdm-simple-slave.h"
52
#include "gdm-server.h"
53
#include "gdm-session.h"
54
#include "gdm-session-glue.h"
55
#include "gdm-launch-environment.h"
56
#include "gdm-settings-direct.h"
57
#include "gdm-settings-keys.h"
59
#define GDM_SIMPLE_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SIMPLE_SLAVE, GdmSimpleSlavePrivate))
61
#define GDM_DBUS_NAME "org.gnome.DisplayManager"
62
#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
64
#define MAX_CONNECT_ATTEMPTS 10
65
#define DEFAULT_PING_INTERVAL 15
67
#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
69
struct GdmSimpleSlavePrivate
72
gint greeter_reset_id;
73
guint start_session_id;
75
char *start_session_service_name;
80
guint connection_attempts;
84
/* we control the user session */
87
/* this spawns and controls the greeter session */
88
GdmLaunchEnvironment *greeter_environment;
90
GHashTable *open_reauthentication_requests;
92
guint start_session_when_ready : 1;
93
guint waiting_to_start_session : 1;
94
guint session_is_running : 1;
95
#ifdef HAVE_LOGINDEVPERM
96
gboolean use_logindevperm;
99
guint plymouth_is_running : 1;
107
static void gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass);
108
static void gdm_simple_slave_init (GdmSimpleSlave *simple_slave);
109
static void gdm_simple_slave_finalize (GObject *object);
110
static void gdm_simple_slave_open_reauthentication_channel (GdmSlave *slave,
111
const char *username,
114
GAsyncReadyCallback callback,
116
GCancellable *cancellable);
118
G_DEFINE_TYPE (GdmSimpleSlave, gdm_simple_slave, GDM_TYPE_SLAVE)
120
static void create_new_session (GdmSimpleSlave *slave);
121
static void start_session (GdmSimpleSlave *slave);
122
static void queue_start_session (GdmSimpleSlave *slave,
123
const char *service_name);
126
on_session_started (GdmSession *session,
127
const char *service_name,
129
GdmSimpleSlave *slave)
134
g_debug ("GdmSimpleSlave: session started %d", pid);
136
slave->priv->session_is_running = TRUE;
138
session_id = gdm_session_get_session_id (session);
139
g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL);
142
/* Run the PreSession script. gdmslave suspends until script has terminated */
143
username = gdm_session_get_username (slave->priv->session);
144
if (username != NULL) {
145
gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PreSession", username);
149
/* FIXME: should we do something here?
150
* Note that error return status from PreSession script should
151
* be ignored in the case of a X-GDM-BypassXsession session, which can
152
* be checked by calling:
153
* gdm_session_bypasses_xsession (session)
157
#ifdef HAVE_LOGINDEVPERM
159
gdm_simple_slave_grant_console_permissions (GdmSimpleSlave *slave)
162
char *display_device;
163
struct passwd *passwd_entry;
165
username = gdm_session_get_username (slave->priv->session);
166
display_device = gdm_session_get_display_device (slave->priv->session);
168
if (username != NULL) {
169
gdm_get_pwent_for_name (username, &passwd_entry);
172
* Only do logindevperm processing if /dev/console or
173
* a device associated with a VT
175
if (display_device != NULL &&
176
(strncmp (display_device, "/dev/vt/", strlen ("/dev/vt/")) == 0 ||
177
strcmp (display_device, "/dev/console") == 0)) {
178
g_debug ("Logindevperm login for user %s, device %s",
179
username, display_device);
180
(void) di_devperm_login (display_device,
181
passwd_entry->pw_uid,
182
passwd_entry->pw_gid,
184
slave->priv->use_logindevperm = TRUE;
188
if (!slave->priv->use_logindevperm) {
189
g_debug ("Not calling di_devperm_login login for user %s, device %s",
190
username, display_device);
195
gdm_simple_slave_revoke_console_permissions (GdmSimpleSlave *slave)
198
char *display_device;
200
username = gdm_session_get_username (slave->priv->session);
201
display_device = gdm_session_get_display_device (slave->priv->session);
204
* Only do logindevperm processing if /dev/console or a device
205
* associated with a VT. Do this after processing the PostSession
206
* script so that permissions for devices are not returned to root
207
* before running the script.
209
if (slave->priv->use_logindevperm == TRUE &&
210
display_device != NULL &&
211
(strncmp (display_device, "/dev/vt/", strlen ("/dev/vt/")) == 0 ||
212
strcmp (display_device, "/dev/console") == 0)) {
213
g_debug ("di_devperm_logout for user %s, device %s",
214
username, display_device);
215
(void) di_devperm_logout (display_device);
216
slave->priv->use_logindevperm = FALSE;
218
g_debug ("Not calling di_devperm_logout logout for user %s, device %s",
219
username, display_device);
223
g_free (display_device);
225
#endif /* HAVE_LOGINDEVPERM */
228
on_session_exited (GdmSession *session,
230
GdmSimpleSlave *slave)
232
g_object_set (GDM_SLAVE (slave), "session-id", NULL, NULL);
234
g_debug ("GdmSimpleSlave: session exited with code %d\n", exit_code);
235
gdm_slave_stop (GDM_SLAVE (slave));
239
on_session_died (GdmSession *session,
241
GdmSimpleSlave *slave)
243
g_object_set (GDM_SLAVE (slave), "session-id", NULL, NULL);
245
g_debug ("GdmSimpleSlave: session died with signal %d, (%s)",
247
g_strsignal (signal_number));
248
gdm_slave_stop (GDM_SLAVE (slave));
252
add_user_authorization (GdmSimpleSlave *slave,
258
username = gdm_session_get_username (slave->priv->session);
259
ret = gdm_slave_add_user_authorization (GDM_SLAVE (slave),
268
reset_session (GdmSimpleSlave *slave)
270
if (slave->priv->session == NULL) {
274
gdm_session_reset (slave->priv->session);
278
greeter_reset_timeout (GdmSimpleSlave *slave)
280
g_debug ("GdmSimpleSlave: resetting greeter");
282
reset_session (slave);
284
slave->priv->greeter_reset_id = 0;
289
queue_greeter_reset (GdmSimpleSlave *slave)
291
if (slave->priv->greeter_reset_id > 0) {
295
slave->priv->greeter_reset_id = g_idle_add ((GSourceFunc)greeter_reset_timeout, slave);
299
gdm_simple_slave_start_session_when_ready (GdmSimpleSlave *slave,
300
const char *service_name)
302
if (slave->priv->start_session_when_ready) {
303
slave->priv->waiting_to_start_session = FALSE;
304
queue_start_session (slave, service_name);
306
slave->priv->waiting_to_start_session = TRUE;
311
try_migrate_session (GdmSimpleSlave *slave)
316
g_debug ("GdmSimpleSlave: trying to migrate session");
318
username = gdm_session_get_username (slave->priv->session);
320
/* try to switch to an existing session */
321
res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username);
328
stop_greeter (GdmSimpleSlave *slave)
331
gboolean script_successful;
333
g_debug ("GdmSimpleSlave: Stopping greeter");
335
if (slave->priv->greeter_environment == NULL) {
336
g_debug ("GdmSimpleSlave: No greeter running");
340
/* Run the PostLogin script. gdmslave suspends until script has terminated */
342
if (slave->priv->session != NULL) {
343
username = gdm_session_get_username (slave->priv->session);
346
if (username != NULL) {
347
script_successful = gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PostLogin", username);
349
script_successful = TRUE;
353
if (!script_successful) {
354
g_debug ("GdmSimpleSlave: PostLogin script unsuccessful");
356
slave->priv->start_session_id = 0;
357
queue_greeter_reset (slave);
361
gdm_launch_environment_stop (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment));
365
start_session (GdmSimpleSlave *slave)
370
add_user_authorization (slave, &auth_file);
372
g_assert (auth_file != NULL);
374
g_object_set (slave->priv->session,
375
"user-x11-authority-file", auth_file,
380
gdm_session_start_session (slave->priv->session,
381
slave->priv->start_session_service_name);
383
slave->priv->start_session_id = 0;
384
g_free (slave->priv->start_session_service_name);
385
slave->priv->start_session_service_name = NULL;
389
start_session_timeout (GdmSimpleSlave *slave)
394
g_debug ("GdmSimpleSlave: accredited");
396
migrated = try_migrate_session (slave);
397
g_debug ("GdmSimpleSlave: migrated: %d", migrated);
399
/* We don't stop the slave here because
400
when Xorg exits it switches to the VT it was
401
started from. That interferes with fast
403
gdm_session_reset (slave->priv->session);
405
slave->priv->start_session_id = 0;
406
g_free (slave->priv->start_session_service_name);
407
slave->priv->start_session_service_name = NULL;
409
if (slave->priv->greeter_environment == NULL) {
411
start_session (slave);
413
/* Session actually gets started from on_greeter_environment_session_stop */
414
stop_greeter (slave);
422
queue_start_session (GdmSimpleSlave *slave,
423
const char *service_name)
425
if (slave->priv->start_session_id > 0) {
429
slave->priv->start_session_id = g_idle_add ((GSourceFunc)start_session_timeout, slave);
430
slave->priv->start_session_service_name = g_strdup (service_name);
434
on_session_reauthenticated (GdmSession *session,
435
const char *service_name,
436
GdmSimpleSlave *slave)
438
try_migrate_session (slave);
442
on_session_opened (GdmSession *session,
443
const char *service_name,
444
const char *session_id,
445
GdmSimpleSlave *slave)
448
#ifdef HAVE_LOGINDEVPERM
449
gdm_simple_slave_grant_console_permissions (slave);
450
#endif /* HAVE_LOGINDEVPERM */
452
if (gdm_session_client_is_connected (slave->priv->session)) {
453
gdm_simple_slave_start_session_when_ready (slave, service_name);
456
slave->priv->start_session_when_ready = TRUE;
457
gdm_simple_slave_start_session_when_ready (slave, service_name);
462
on_session_conversation_started (GdmSession *session,
463
const char *service_name,
464
GdmSimpleSlave *slave)
470
g_debug ("GdmSimpleSlave: session conversation started for service %s", service_name);
472
if (g_strcmp0 (service_name, "gdm-autologin") != 0) {
477
gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, &username, &delay);
483
g_debug ("GdmSimpleSlave: begin auto login for user '%s'", username);
484
/* service_name will be "gdm-autologin"
486
gdm_session_setup_for_user (slave->priv->session, service_name, username);
493
on_session_conversation_stopped (GdmSession *session,
494
const char *service_name,
495
GdmSimpleSlave *slave)
497
g_debug ("GdmSimpleSlave: conversation stopped");
502
start_autologin_conversation_if_necessary (GdmSimpleSlave *slave)
506
gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, NULL);
512
g_debug ("GdmSimpleSlave: Starting automatic login conversation");
513
gdm_session_start_conversation (slave->priv->session, "gdm-autologin");
517
on_session_reauthentication_started (GdmSession *session,
520
GdmSimpleSlave *slave)
522
GSimpleAsyncResult *result;
525
g_debug ("GdmSimpleSlave: reauthentication started");
527
source_tag = GINT_TO_POINTER (pid_of_caller);
529
result = g_hash_table_lookup (slave->priv->open_reauthentication_requests,
532
if (result != NULL) {
533
g_simple_async_result_set_op_res_gpointer (result,
537
g_simple_async_result_complete_in_idle (result);
540
g_hash_table_remove (slave->priv->open_reauthentication_requests,
545
on_session_client_ready_for_session_to_start (GdmSession *session,
546
const char *service_name,
547
gboolean client_is_ready,
548
GdmSimpleSlave *slave)
550
if (client_is_ready) {
551
g_debug ("GdmSimpleSlave: Will start session when ready");
553
g_debug ("GdmSimpleSlave: Will start session when ready and told");
556
if (slave->priv->greeter_reset_id > 0) {
560
slave->priv->start_session_when_ready = client_is_ready;
562
if (client_is_ready && slave->priv->waiting_to_start_session) {
563
gdm_simple_slave_start_session_when_ready (slave, service_name);
568
on_ready_to_request_timed_login (GdmSession *session,
569
GSimpleAsyncResult *result,
572
int delay = GPOINTER_TO_INT (user_data);
573
GCancellable *cancellable;
576
cancellable = g_object_get_data (G_OBJECT (result),
578
if (g_cancellable_is_cancelled (cancellable)) {
582
username = g_simple_async_result_get_source_tag (result);
584
gdm_session_request_timed_login (session, username, delay);
586
g_object_weak_unref (G_OBJECT (session),
588
g_cancellable_cancel,
590
g_object_weak_unref (G_OBJECT (session),
594
g_object_weak_unref (G_OBJECT (session),
603
on_wait_for_greeter_timeout (GSimpleAsyncResult *result)
605
g_simple_async_result_complete (result);
611
on_session_client_connected (GdmSession *session,
612
GCredentials *credentials,
614
GdmSimpleSlave *slave)
616
gboolean timed_login_enabled;
619
gboolean display_is_local;
621
g_debug ("GdmSimpleSlave: client connected");
624
"display-is-local", &display_is_local,
627
/* If XDMCP stop pinging */
628
if ( ! display_is_local) {
632
timed_login_enabled = FALSE;
633
gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &timed_login_enabled, &username, &delay);
635
if (! timed_login_enabled) {
639
/* temporary hack to fix timed login
640
* http://bugzilla.gnome.org/680348
643
GSimpleAsyncResult *result;
644
GCancellable *cancellable;
648
delay = MAX (delay, 4);
650
cancellable = g_cancellable_new ();
651
source_tag = g_strdup (username);
652
result = g_simple_async_result_new (G_OBJECT (session),
653
(GAsyncReadyCallback)
654
on_ready_to_request_timed_login,
655
GINT_TO_POINTER (delay),
657
g_simple_async_result_set_check_cancellable (result, cancellable);
658
g_object_set_data (G_OBJECT (result),
662
timeout_id = g_timeout_add_seconds_full (delay - 2,
665
on_wait_for_greeter_timeout,
666
g_object_ref (result),
669
g_cancellable_connect (cancellable,
670
G_CALLBACK (g_source_remove),
671
GINT_TO_POINTER (timeout_id),
674
g_object_weak_ref (G_OBJECT (session),
676
g_cancellable_cancel,
678
g_object_weak_ref (G_OBJECT (session),
682
g_object_weak_ref (G_OBJECT (session),
692
on_session_client_disconnected (GdmSession *session,
693
GCredentials *credentials,
695
GdmSimpleSlave *slave)
697
gboolean display_is_local;
699
g_debug ("GdmSimpleSlave: client disconnected");
702
"display-is-local", &display_is_local,
705
if ( ! display_is_local && !slave->priv->session_is_running) {
706
gdm_slave_stop (GDM_SLAVE (slave));
711
on_session_cancelled (GdmSession *session,
712
GdmSimpleSlave *slave)
714
g_debug ("GdmSimpleSlave: Session was cancelled");
715
queue_greeter_reset (slave);
719
create_new_session (GdmSimpleSlave *slave)
721
gboolean display_is_local;
724
char *display_hostname;
725
char *display_device;
726
char *display_seat_id;
727
char *display_x11_authority_file;
728
GdmSession *greeter_session;
731
g_debug ("GdmSimpleSlave: Creating new session");
733
if (slave->priv->greeter_environment != NULL) {
734
greeter_session = gdm_launch_environment_get_session (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment));
735
greeter_uid = gdm_session_get_allowed_user (greeter_session);
741
"display-id", &display_id,
742
"display-name", &display_name,
743
"display-hostname", &display_hostname,
744
"display-is-local", &display_is_local,
745
"display-x11-authority-file", &display_x11_authority_file,
746
"display-seat-id", &display_seat_id,
749
display_device = NULL;
750
if (slave->priv->server != NULL) {
751
display_device = gdm_server_get_display_device (slave->priv->server);
754
slave->priv->session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN,
760
display_x11_authority_file,
765
g_free (display_name);
766
g_free (display_device);
767
g_free (display_hostname);
769
g_signal_connect (slave->priv->session,
770
"reauthentication-started",
771
G_CALLBACK (on_session_reauthentication_started),
773
g_signal_connect (slave->priv->session,
775
G_CALLBACK (on_session_reauthenticated),
777
g_signal_connect (slave->priv->session,
778
"client-ready-for-session-to-start",
779
G_CALLBACK (on_session_client_ready_for_session_to_start),
781
g_signal_connect (slave->priv->session,
783
G_CALLBACK (on_session_client_connected),
785
g_signal_connect (slave->priv->session,
786
"client-disconnected",
787
G_CALLBACK (on_session_client_disconnected),
789
g_signal_connect (slave->priv->session,
791
G_CALLBACK (on_session_cancelled),
793
g_signal_connect (slave->priv->session,
794
"conversation-started",
795
G_CALLBACK (on_session_conversation_started),
797
g_signal_connect (slave->priv->session,
798
"conversation-stopped",
799
G_CALLBACK (on_session_conversation_stopped),
801
g_signal_connect (slave->priv->session,
803
G_CALLBACK (on_session_opened),
805
g_signal_connect (slave->priv->session,
807
G_CALLBACK (on_session_started),
809
g_signal_connect (slave->priv->session,
811
G_CALLBACK (on_session_exited),
813
g_signal_connect (slave->priv->session,
815
G_CALLBACK (on_session_died),
818
start_autologin_conversation_if_necessary (slave);
822
on_greeter_environment_session_opened (GdmLaunchEnvironment *greeter_environment,
823
GdmSimpleSlave *slave)
827
g_debug ("GdmSimpleSlave: Greeter session opened");
828
session_id = gdm_launch_environment_get_session_id (GDM_LAUNCH_ENVIRONMENT (greeter_environment));
830
g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL);
835
on_greeter_environment_session_started (GdmLaunchEnvironment *greeter_environment,
836
GdmSimpleSlave *slave)
838
g_debug ("GdmSimpleSlave: Greeter started");
842
on_greeter_environment_session_stopped (GdmLaunchEnvironment *greeter_environment,
843
GdmSimpleSlave *slave)
845
g_debug ("GdmSimpleSlave: Greeter stopped");
846
if (slave->priv->start_session_service_name == NULL) {
847
gdm_slave_stop (GDM_SLAVE (slave));
849
start_session (slave);
852
g_object_unref (slave->priv->greeter_environment);
853
slave->priv->greeter_environment = NULL;
857
on_greeter_environment_session_exited (GdmLaunchEnvironment *greeter_environment,
859
GdmSimpleSlave *slave)
861
g_debug ("GdmSimpleSlave: Greeter exited: %d", code);
862
if (slave->priv->start_session_service_name == NULL) {
863
gdm_slave_stop (GDM_SLAVE (slave));
868
on_greeter_environment_session_died (GdmLaunchEnvironment *greeter_environment,
870
GdmSimpleSlave *slave)
872
g_debug ("GdmSimpleSlave: Greeter died: %d", signal);
873
if (slave->priv->start_session_service_name == NULL) {
874
gdm_slave_stop (GDM_SLAVE (slave));
880
plymouth_is_running (void)
887
res = g_spawn_command_line_sync ("/bin/plymouth --ping",
888
NULL, NULL, &status, &error);
890
g_debug ("Could not ping plymouth: %s", error->message);
891
g_error_free (error);
895
return WIFEXITED (status) && WEXITSTATUS (status) == 0;
899
plymouth_prepare_for_transition (GdmSimpleSlave *slave)
905
res = g_spawn_command_line_sync ("/bin/plymouth deactivate",
906
NULL, NULL, NULL, &error);
908
g_warning ("Could not deactivate plymouth: %s", error->message);
909
g_error_free (error);
914
plymouth_quit_with_transition (GdmSimpleSlave *slave)
920
res = g_spawn_command_line_sync ("/bin/plymouth quit --retain-splash",
921
NULL, NULL, NULL, &error);
923
g_warning ("Could not quit plymouth: %s", error->message);
924
g_error_free (error);
926
slave->priv->plymouth_is_running = FALSE;
930
plymouth_quit_without_transition (GdmSimpleSlave *slave)
936
res = g_spawn_command_line_sync ("/bin/plymouth quit",
937
NULL, NULL, NULL, &error);
939
g_warning ("Could not quit plymouth: %s", error->message);
940
g_error_free (error);
942
slave->priv->plymouth_is_running = FALSE;
947
setup_server (GdmSimpleSlave *slave)
949
/* Put cursor out of the way on first head */
950
gdm_slave_set_initial_cursor_position (GDM_SLAVE (slave));
952
/* Set the busy cursor */
953
gdm_slave_set_busy_cursor (GDM_SLAVE (slave));
955
/* The root window has a background that may be useful
956
* to cross fade or transition from when setting the
957
* login screen background. We read it here, and stuff
958
* it into the standard _XROOTPMAP_ID root window property,
959
* so gnome-settings-daemon can get at it.
961
gdm_slave_save_root_windows (GDM_SLAVE (slave));
964
/* Plymouth is waiting for the go-ahead to exit */
965
if (slave->priv->plymouth_is_running) {
966
plymouth_quit_with_transition (slave);
971
static GdmLaunchEnvironment *
972
create_environment (const char *session_id,
973
const char *user_name,
974
const char *display_name,
976
const char *display_device,
977
const char *display_hostname,
978
gboolean display_is_local)
980
gboolean debug = FALSE;
982
GdmLaunchEnvironment *launch_environment;
986
gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug);
988
args = g_ptr_array_new ();
989
g_ptr_array_add (args, BINDIR "/gnome-session");
991
g_ptr_array_add (args, "--autostart");
992
g_ptr_array_add (args, DATADIR "/gdm/greeter/autostart");
995
g_ptr_array_add (args, "--debug");
998
if (session_id != NULL) {
999
g_ptr_array_add (args, " --session");
1000
g_ptr_array_add (args, (char *) session_id);
1003
g_ptr_array_add (args, NULL);
1005
argv = (char **) g_ptr_array_free (args, FALSE);
1006
command = g_strjoinv (" ", argv);
1009
launch_environment = g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT,
1011
"user-name", user_name,
1012
"x11-display-name", display_name,
1013
"x11-display-seat-id", seat_id,
1014
"x11-display-device", display_device,
1015
"x11-display-hostname", display_hostname,
1016
"x11-display-is-local", display_is_local,
1017
"runtime-dir", GDM_SCREENSHOT_DIR,
1021
return launch_environment;
1025
start_launch_environment (GdmSimpleSlave *slave,
1029
gboolean display_is_local;
1033
char *display_device;
1034
char *display_hostname;
1038
g_debug ("GdmSimpleSlave: Running greeter");
1040
display_is_local = FALSE;
1042
display_name = NULL;
1045
display_device = NULL;
1046
display_hostname = NULL;
1048
g_object_get (slave,
1049
"display-id", &display_id,
1050
"display-is-local", &display_is_local,
1051
"display-name", &display_name,
1052
"display-seat-id", &seat_id,
1053
"display-hostname", &display_hostname,
1054
"display-x11-authority-file", &auth_file,
1057
g_debug ("GdmSimpleSlave: Creating greeter for %s %s", display_name, display_hostname);
1059
if (slave->priv->server != NULL) {
1060
display_device = gdm_server_get_display_device (slave->priv->server);
1063
/* FIXME: send a signal back to the master */
1065
/* If XDMCP setup pinging */
1066
slave->priv->ping_interval = DEFAULT_PING_INTERVAL;
1067
res = gdm_settings_direct_get_int (GDM_KEY_PING_INTERVAL,
1068
&(slave->priv->ping_interval));
1070
if ( ! display_is_local && res && slave->priv->ping_interval > 0) {
1071
alarm (slave->priv->ping_interval);
1074
/* Run the init script. gdmslave suspends until script has terminated */
1075
gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
1077
g_debug ("GdmSimpleSlave: Creating greeter on %s %s %s", display_name, display_device, display_hostname);
1078
slave->priv->greeter_environment = create_environment (session_id,
1085
g_signal_connect (slave->priv->greeter_environment,
1087
G_CALLBACK (on_greeter_environment_session_opened),
1089
g_signal_connect (slave->priv->greeter_environment,
1091
G_CALLBACK (on_greeter_environment_session_started),
1093
g_signal_connect (slave->priv->greeter_environment,
1095
G_CALLBACK (on_greeter_environment_session_stopped),
1097
g_signal_connect (slave->priv->greeter_environment,
1099
G_CALLBACK (on_greeter_environment_session_exited),
1101
g_signal_connect (slave->priv->greeter_environment,
1103
G_CALLBACK (on_greeter_environment_session_died),
1105
g_object_set (slave->priv->greeter_environment,
1106
"x11-authority-file", auth_file,
1109
gdm_launch_environment_start (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment));
1111
g_free (display_id);
1112
g_free (display_name);
1114
g_free (display_device);
1115
g_free (display_hostname);
1120
start_greeter (GdmSimpleSlave *slave)
1122
start_launch_environment (slave, GDM_USERNAME, NULL);
1125
#define RULES_DIR LOCALSTATEDIR "/lib/polkit-1/localauthority/10-vendor.d/"
1126
#define RULES_FILE "20-gnome-initial-setup.rules"
1128
static const gboolean
1129
create_initial_setup_user (GdmSimpleSlave *slave)
1131
gboolean ret = TRUE;
1132
ActUserManager *act;
1134
GFile *src_file, *dest_file;
1135
GError *error = NULL;
1136
const char *e = NULL;
1138
/* First, create the user */
1139
act = act_user_manager_get_default ();
1141
user = act_user_manager_create_user (act, INITIAL_SETUP_USERNAME, "", 0, &error);
1143
if (g_dbus_error_is_remote_error (error)) {
1144
e = g_dbus_error_get_remote_error (error);
1147
g_warning ("Creating user '%s' failed: %s / %s",
1148
INITIAL_SETUP_USERNAME, e, error->message);
1150
if (g_strcmp0 (e, "org.freedesktop.Accounts.Error.UserExists") != 0) {
1155
g_object_unref (user);
1158
/* Now, make sure the PolicyKit policy is in place */
1159
src_file = g_file_new_for_path (DATADIR "/gnome-initial-setup" RULES_FILE);
1160
dest_file = g_file_new_for_path (RULES_DIR RULES_FILE);
1162
if (!g_file_copy (src_file,
1164
G_FILE_COPY_OVERWRITE,
1165
NULL, NULL, NULL, &error)) {
1166
g_warning ("Failed to copy '%s' to '%s': %s",
1167
g_file_get_path (src_file),
1168
g_file_get_path (dest_file),
1171
goto out_clear_files;
1175
g_object_unref (src_file);
1176
g_object_unref (dest_file);
1179
g_clear_pointer (&e, g_free);
1180
g_clear_error (&error);
1185
destroy_initial_setup_user (GdmSimpleSlave *slave)
1187
ActUserManager *act;
1189
const char *filename;
1192
filename = RULES_DIR RULES_FILE;
1194
if (g_remove (filename) < 0) {
1195
g_warning ("Failed to remove '%s': %s", filename, g_strerror (errno));
1198
act = act_user_manager_get_default ();
1201
user = act_user_manager_get_user (act, INITIAL_SETUP_USERNAME);
1202
if (!act_user_manager_delete_user (act, user, TRUE, &error)) {
1203
g_warning ("Failed to delete user '%s': %s", INITIAL_SETUP_USERNAME, error->message);
1204
g_error_free (error);
1207
g_object_unref (user);
1211
start_initial_setup (GdmSimpleSlave *slave)
1213
create_initial_setup_user (slave);
1214
start_launch_environment (slave, INITIAL_SETUP_USERNAME, "gnome-initial-setup");
1215
destroy_initial_setup_user (slave);
1219
wants_autologin (GdmSimpleSlave *slave)
1221
gboolean enabled = FALSE;
1223
/* FIXME: handle wait-for-go */
1225
gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay);
1226
return enabled && delay == 0;
1229
#define INITIAL_SETUP_TRIGGER_FILE LOCALSTATEDIR "/lib/gdm/run-initial-setup"
1232
wants_initial_setup (GdmSimpleSlave *slave)
1236
if (!g_file_test (INITIAL_SETUP_TRIGGER_FILE, G_FILE_TEST_EXISTS)) {
1240
if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) {
1252
idle_connect_to_display (GdmSimpleSlave *slave)
1256
slave->priv->connection_attempts++;
1258
res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave));
1260
setup_server (slave);
1262
if (wants_initial_setup (slave)) {
1263
start_initial_setup (slave);
1264
} else if (wants_autologin (slave)) {
1265
/* Run the init script. gdmslave suspends until script has terminated */
1266
gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
1268
start_greeter (slave);
1270
create_new_session (slave);
1272
if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) {
1273
g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts);
1283
on_server_ready (GdmServer *server,
1284
GdmSimpleSlave *slave)
1286
g_idle_add ((GSourceFunc)idle_connect_to_display, slave);
1290
on_server_exited (GdmServer *server,
1292
GdmSimpleSlave *slave)
1294
g_debug ("GdmSimpleSlave: server exited with code %d\n", exit_code);
1296
gdm_slave_stop (GDM_SLAVE (slave));
1298
#ifdef WITH_PLYMOUTH
1299
if (slave->priv->plymouth_is_running) {
1300
plymouth_quit_without_transition (slave);
1306
on_server_died (GdmServer *server,
1308
GdmSimpleSlave *slave)
1310
g_debug ("GdmSimpleSlave: server died with signal %d, (%s)",
1312
g_strsignal (signal_number));
1314
gdm_slave_stop (GDM_SLAVE (slave));
1316
#ifdef WITH_PLYMOUTH
1317
if (slave->priv->plymouth_is_running) {
1318
plymouth_quit_without_transition (slave);
1324
gdm_simple_slave_run (GdmSimpleSlave *slave)
1329
gboolean display_is_local;
1330
gboolean display_is_initial;
1332
g_object_get (slave,
1333
"display-is-local", &display_is_local,
1334
"display-name", &display_name,
1335
"display-seat-id", &seat_id,
1336
"display-x11-authority-file", &auth_file,
1337
"display-is-initial", &display_is_initial,
1340
/* if this is local display start a server if one doesn't
1342
if (display_is_local) {
1344
gboolean disable_tcp;
1346
slave->priv->server = gdm_server_new (display_name, seat_id, auth_file, display_is_initial);
1349
if (gdm_settings_client_get_boolean (GDM_KEY_DISALLOW_TCP,
1351
g_object_set (slave->priv->server,
1352
"disable-tcp", disable_tcp,
1356
g_signal_connect (slave->priv->server,
1358
G_CALLBACK (on_server_exited),
1360
g_signal_connect (slave->priv->server,
1362
G_CALLBACK (on_server_died),
1364
g_signal_connect (slave->priv->server,
1366
G_CALLBACK (on_server_ready),
1369
#ifdef WITH_PLYMOUTH
1370
slave->priv->plymouth_is_running = plymouth_is_running ();
1372
if (slave->priv->plymouth_is_running) {
1373
plymouth_prepare_for_transition (slave);
1376
res = gdm_server_start (slave->priv->server);
1378
g_warning (_("Could not start the X "
1379
"server (your graphical environment) "
1380
"due to an internal error. "
1381
"Please contact your system administrator "
1382
"or check your syslog to diagnose. "
1383
"In the meantime this display will be "
1384
"disabled. Please restart GDM when "
1385
"the problem is corrected."));
1386
#ifdef WITH_PLYMOUTH
1387
if (slave->priv->plymouth_is_running) {
1388
plymouth_quit_without_transition (slave);
1394
g_debug ("GdmSimpleSlave: Started X server");
1396
g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
1399
g_free (display_name);
1406
gdm_simple_slave_open_session (GdmSlave *slave,
1408
uid_t uid_of_caller,
1412
GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
1415
if (self->priv->session_is_running) {
1418
G_DBUS_ERROR_ACCESS_DENIED,
1419
_("Can only be called before user is logged in"));
1423
allowed_user = gdm_session_get_allowed_user (self->priv->session);
1425
if (uid_of_caller != allowed_user) {
1428
G_DBUS_ERROR_ACCESS_DENIED,
1429
_("Caller not GDM"));
1433
*address = gdm_session_get_server_address (self->priv->session);
1439
gdm_simple_slave_open_reauthentication_channel_finish (GdmSlave *slave,
1440
GAsyncResult *result,
1443
GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
1444
const char *address;
1446
g_return_val_if_fail (g_simple_async_result_is_valid (result,
1448
gdm_simple_slave_open_reauthentication_channel), NULL);
1450
address = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1452
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) {
1456
return g_strdup (address);
1460
gdm_simple_slave_open_reauthentication_channel (GdmSlave *slave,
1461
const char *username,
1463
uid_t uid_of_caller,
1464
GAsyncReadyCallback callback,
1466
GCancellable *cancellable)
1468
GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
1469
GSimpleAsyncResult *result;
1471
result = g_simple_async_result_new (G_OBJECT (slave),
1474
gdm_simple_slave_open_reauthentication_channel);
1476
g_simple_async_result_set_check_cancellable (result, cancellable);
1478
if (!self->priv->session_is_running) {
1479
g_simple_async_result_set_error (result,
1481
G_DBUS_ERROR_ACCESS_DENIED,
1482
_("User not logged in"));
1483
g_simple_async_result_complete_in_idle (result);
1486
g_hash_table_insert (self->priv->open_reauthentication_requests,
1487
GINT_TO_POINTER (pid_of_caller),
1488
g_object_ref (result));
1490
gdm_session_start_reauthentication (self->priv->session,
1495
g_object_unref (result);
1499
gdm_simple_slave_start (GdmSlave *slave)
1501
GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->start (slave);
1503
gdm_simple_slave_run (GDM_SIMPLE_SLAVE (slave));
1509
gdm_simple_slave_stop (GdmSlave *slave)
1511
GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
1513
g_debug ("GdmSimpleSlave: Stopping simple_slave");
1515
GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->stop (slave);
1517
if (self->priv->greeter_environment != NULL) {
1518
stop_greeter (self);
1519
self->priv->greeter_environment = NULL;
1522
if (self->priv->session_is_running) {
1525
/* Run the PostSession script. gdmslave suspends until script
1528
username = gdm_session_get_username (self->priv->session);
1529
if (username != NULL) {
1530
gdm_slave_run_script (slave, GDMCONFDIR "/PostSession", username);
1534
#ifdef HAVE_LOGINDEVPERM
1535
gdm_simple_slave_revoke_console_permissions (self);
1538
self->priv->session_is_running = FALSE;
1541
if (self->priv->session != NULL) {
1542
gdm_session_close (self->priv->session);
1543
g_clear_object (&self->priv->session);
1546
if (self->priv->server != NULL) {
1547
gdm_server_stop (self->priv->server);
1548
g_clear_object (&self->priv->server);
1555
gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass)
1557
GObjectClass *object_class = G_OBJECT_CLASS (klass);
1558
GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass);
1560
object_class->finalize = gdm_simple_slave_finalize;
1562
slave_class->start = gdm_simple_slave_start;
1563
slave_class->stop = gdm_simple_slave_stop;
1564
slave_class->open_session = gdm_simple_slave_open_session;
1565
slave_class->open_reauthentication_channel = gdm_simple_slave_open_reauthentication_channel;
1566
slave_class->open_reauthentication_channel_finish = gdm_simple_slave_open_reauthentication_channel_finish;
1568
g_type_class_add_private (klass, sizeof (GdmSimpleSlavePrivate));
1572
gdm_simple_slave_init (GdmSimpleSlave *slave)
1574
slave->priv = GDM_SIMPLE_SLAVE_GET_PRIVATE (slave);
1575
#ifdef HAVE_LOGINDEVPERM
1576
slave->priv->use_logindevperm = FALSE;
1579
slave->priv->open_reauthentication_requests = g_hash_table_new_full (NULL,
1588
gdm_simple_slave_finalize (GObject *object)
1590
GdmSimpleSlave *slave;
1592
g_return_if_fail (object != NULL);
1593
g_return_if_fail (GDM_IS_SIMPLE_SLAVE (object));
1595
slave = GDM_SIMPLE_SLAVE (object);
1597
g_return_if_fail (slave->priv != NULL);
1599
gdm_slave_stop (GDM_SLAVE (slave));
1601
g_hash_table_unref (slave->priv->open_reauthentication_requests);
1603
if (slave->priv->greeter_reset_id > 0) {
1604
g_source_remove (slave->priv->greeter_reset_id);
1605
slave->priv->greeter_reset_id = 0;
1608
G_OBJECT_CLASS (gdm_simple_slave_parent_class)->finalize (object);
1612
gdm_simple_slave_new (const char *id)
1616
object = g_object_new (GDM_TYPE_SIMPLE_SLAVE,
1620
return GDM_SLAVE (object);