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)
471
g_debug ("GdmSimpleSlave: session conversation started");
473
gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, &username, &delay);
479
g_debug ("GdmSimpleSlave: begin auto login for user '%s'", username);
480
/* service_name will be "gdm-autologin"
482
gdm_session_setup_for_user (slave->priv->session, service_name, username);
489
on_session_conversation_stopped (GdmSession *session,
490
const char *service_name,
491
GdmSimpleSlave *slave)
493
g_debug ("GdmSimpleSlave: conversation stopped");
498
start_autologin_conversation_if_necessary (GdmSimpleSlave *slave)
502
gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, NULL);
508
g_debug ("GdmSimpleSlave: Starting automatic login conversation");
509
gdm_session_start_conversation (slave->priv->session, "gdm-autologin");
513
on_session_reauthentication_started (GdmSession *session,
516
GdmSimpleSlave *slave)
518
GSimpleAsyncResult *result;
521
g_debug ("GdmSimpleSlave: reauthentication started");
523
source_tag = GINT_TO_POINTER (pid_of_caller);
525
result = g_hash_table_lookup (slave->priv->open_reauthentication_requests,
528
if (result != NULL) {
529
g_simple_async_result_set_op_res_gpointer (result,
533
g_simple_async_result_complete_in_idle (result);
536
g_hash_table_remove (slave->priv->open_reauthentication_requests,
541
on_session_client_ready_for_session_to_start (GdmSession *session,
542
const char *service_name,
543
gboolean client_is_ready,
544
GdmSimpleSlave *slave)
546
if (client_is_ready) {
547
g_debug ("GdmSimpleSlave: Will start session when ready");
549
g_debug ("GdmSimpleSlave: Will start session when ready and told");
552
if (slave->priv->greeter_reset_id > 0) {
556
slave->priv->start_session_when_ready = client_is_ready;
558
if (client_is_ready && slave->priv->waiting_to_start_session) {
559
gdm_simple_slave_start_session_when_ready (slave, service_name);
564
on_ready_to_request_timed_login (GdmSession *session,
565
GSimpleAsyncResult *result,
568
int delay = GPOINTER_TO_INT (user_data);
569
GCancellable *cancellable;
572
cancellable = g_object_get_data (G_OBJECT (result),
574
if (g_cancellable_is_cancelled (cancellable)) {
578
username = g_simple_async_result_get_source_tag (result);
580
gdm_session_request_timed_login (session, username, delay);
582
g_object_weak_unref (G_OBJECT (session),
584
g_cancellable_cancel,
586
g_object_weak_unref (G_OBJECT (session),
590
g_object_weak_unref (G_OBJECT (session),
599
on_wait_for_greeter_timeout (GSimpleAsyncResult *result)
601
g_simple_async_result_complete (result);
607
on_session_client_connected (GdmSession *session,
608
GCredentials *credentials,
610
GdmSimpleSlave *slave)
612
gboolean timed_login_enabled;
615
gboolean display_is_local;
617
g_debug ("GdmSimpleSlave: client connected");
620
"display-is-local", &display_is_local,
623
/* If XDMCP stop pinging */
624
if ( ! display_is_local) {
628
timed_login_enabled = FALSE;
629
gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &timed_login_enabled, &username, &delay);
631
if (! timed_login_enabled) {
635
/* temporary hack to fix timed login
636
* http://bugzilla.gnome.org/680348
639
GSimpleAsyncResult *result;
640
GCancellable *cancellable;
644
delay = MAX (delay, 4);
646
cancellable = g_cancellable_new ();
647
source_tag = g_strdup (username);
648
result = g_simple_async_result_new (G_OBJECT (session),
649
(GAsyncReadyCallback)
650
on_ready_to_request_timed_login,
651
GINT_TO_POINTER (delay),
653
g_simple_async_result_set_check_cancellable (result, cancellable);
654
g_object_set_data (G_OBJECT (result),
658
timeout_id = g_timeout_add_seconds_full (delay - 2,
661
on_wait_for_greeter_timeout,
662
g_object_ref (result),
665
g_cancellable_connect (cancellable,
666
G_CALLBACK (g_source_remove),
667
GINT_TO_POINTER (timeout_id),
670
g_object_weak_ref (G_OBJECT (session),
672
g_cancellable_cancel,
674
g_object_weak_ref (G_OBJECT (session),
678
g_object_weak_ref (G_OBJECT (session),
688
on_session_client_disconnected (GdmSession *session,
689
GCredentials *credentials,
691
GdmSimpleSlave *slave)
693
gboolean display_is_local;
695
g_debug ("GdmSimpleSlave: client disconnected");
698
"display-is-local", &display_is_local,
701
if ( ! display_is_local && !slave->priv->session_is_running) {
702
gdm_slave_stop (GDM_SLAVE (slave));
707
on_session_cancelled (GdmSession *session,
708
GdmSimpleSlave *slave)
710
g_debug ("GdmSimpleSlave: Session was cancelled");
711
queue_greeter_reset (slave);
715
create_new_session (GdmSimpleSlave *slave)
717
gboolean display_is_local;
720
char *display_hostname;
721
char *display_device;
722
char *display_seat_id;
723
char *display_x11_authority_file;
724
GdmSession *greeter_session;
727
g_debug ("GdmSimpleSlave: Creating new session");
729
if (slave->priv->greeter_environment != NULL) {
730
greeter_session = gdm_launch_environment_get_session (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment));
731
greeter_uid = gdm_session_get_allowed_user (greeter_session);
737
"display-id", &display_id,
738
"display-name", &display_name,
739
"display-hostname", &display_hostname,
740
"display-is-local", &display_is_local,
741
"display-x11-authority-file", &display_x11_authority_file,
742
"display-seat-id", &display_seat_id,
745
display_device = NULL;
746
if (slave->priv->server != NULL) {
747
display_device = gdm_server_get_display_device (slave->priv->server);
750
slave->priv->session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN,
756
display_x11_authority_file,
761
g_free (display_name);
762
g_free (display_device);
763
g_free (display_hostname);
765
g_signal_connect (slave->priv->session,
766
"reauthentication-started",
767
G_CALLBACK (on_session_reauthentication_started),
769
g_signal_connect (slave->priv->session,
771
G_CALLBACK (on_session_reauthenticated),
773
g_signal_connect (slave->priv->session,
774
"client-ready-for-session-to-start",
775
G_CALLBACK (on_session_client_ready_for_session_to_start),
777
g_signal_connect (slave->priv->session,
779
G_CALLBACK (on_session_client_connected),
781
g_signal_connect (slave->priv->session,
782
"client-disconnected",
783
G_CALLBACK (on_session_client_disconnected),
785
g_signal_connect (slave->priv->session,
787
G_CALLBACK (on_session_cancelled),
789
g_signal_connect (slave->priv->session,
790
"conversation-started",
791
G_CALLBACK (on_session_conversation_started),
793
g_signal_connect (slave->priv->session,
794
"conversation-stopped",
795
G_CALLBACK (on_session_conversation_stopped),
797
g_signal_connect (slave->priv->session,
799
G_CALLBACK (on_session_opened),
801
g_signal_connect (slave->priv->session,
803
G_CALLBACK (on_session_started),
805
g_signal_connect (slave->priv->session,
807
G_CALLBACK (on_session_exited),
809
g_signal_connect (slave->priv->session,
811
G_CALLBACK (on_session_died),
814
start_autologin_conversation_if_necessary (slave);
818
on_greeter_environment_session_opened (GdmLaunchEnvironment *greeter_environment,
819
GdmSimpleSlave *slave)
823
g_debug ("GdmSimpleSlave: Greeter session opened");
824
session_id = gdm_launch_environment_get_session_id (GDM_LAUNCH_ENVIRONMENT (greeter_environment));
826
g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL);
831
on_greeter_environment_session_started (GdmLaunchEnvironment *greeter_environment,
832
GdmSimpleSlave *slave)
834
g_debug ("GdmSimpleSlave: Greeter started");
838
on_greeter_environment_session_stopped (GdmLaunchEnvironment *greeter_environment,
839
GdmSimpleSlave *slave)
841
g_debug ("GdmSimpleSlave: Greeter stopped");
842
if (slave->priv->start_session_service_name == NULL) {
843
gdm_slave_stop (GDM_SLAVE (slave));
845
start_session (slave);
848
g_object_unref (slave->priv->greeter_environment);
849
slave->priv->greeter_environment = NULL;
853
on_greeter_environment_session_exited (GdmLaunchEnvironment *greeter_environment,
855
GdmSimpleSlave *slave)
857
g_debug ("GdmSimpleSlave: Greeter exited: %d", code);
858
if (slave->priv->start_session_service_name == NULL) {
859
gdm_slave_stop (GDM_SLAVE (slave));
864
on_greeter_environment_session_died (GdmLaunchEnvironment *greeter_environment,
866
GdmSimpleSlave *slave)
868
g_debug ("GdmSimpleSlave: Greeter died: %d", signal);
869
if (slave->priv->start_session_service_name == NULL) {
870
gdm_slave_stop (GDM_SLAVE (slave));
876
plymouth_is_running (void)
883
res = g_spawn_command_line_sync ("/bin/plymouth --ping",
884
NULL, NULL, &status, &error);
886
g_debug ("Could not ping plymouth: %s", error->message);
887
g_error_free (error);
891
return WIFEXITED (status) && WEXITSTATUS (status) == 0;
895
plymouth_prepare_for_transition (GdmSimpleSlave *slave)
901
res = g_spawn_command_line_sync ("/bin/plymouth deactivate",
902
NULL, NULL, NULL, &error);
904
g_warning ("Could not deactivate plymouth: %s", error->message);
905
g_error_free (error);
910
plymouth_quit_with_transition (GdmSimpleSlave *slave)
916
res = g_spawn_command_line_sync ("/bin/plymouth quit --retain-splash",
917
NULL, NULL, NULL, &error);
919
g_warning ("Could not quit plymouth: %s", error->message);
920
g_error_free (error);
922
slave->priv->plymouth_is_running = FALSE;
926
plymouth_quit_without_transition (GdmSimpleSlave *slave)
932
res = g_spawn_command_line_sync ("/bin/plymouth quit",
933
NULL, NULL, NULL, &error);
935
g_warning ("Could not quit plymouth: %s", error->message);
936
g_error_free (error);
938
slave->priv->plymouth_is_running = FALSE;
943
setup_server (GdmSimpleSlave *slave)
945
/* Put cursor out of the way on first head */
946
gdm_slave_set_initial_cursor_position (GDM_SLAVE (slave));
948
/* Set the busy cursor */
949
gdm_slave_set_busy_cursor (GDM_SLAVE (slave));
951
/* The root window has a background that may be useful
952
* to cross fade or transition from when setting the
953
* login screen background. We read it here, and stuff
954
* it into the standard _XROOTPMAP_ID root window property,
955
* so gnome-settings-daemon can get at it.
957
gdm_slave_save_root_windows (GDM_SLAVE (slave));
960
/* Plymouth is waiting for the go-ahead to exit */
961
if (slave->priv->plymouth_is_running) {
962
plymouth_quit_with_transition (slave);
967
static GdmLaunchEnvironment *
968
create_environment (const char *session_id,
969
const char *user_name,
970
const char *display_name,
972
const char *display_device,
973
const char *display_hostname,
974
gboolean display_is_local)
976
gboolean debug = FALSE;
978
GdmLaunchEnvironment *launch_environment;
982
gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug);
984
args = g_ptr_array_new ();
985
g_ptr_array_add (args, BINDIR "/gnome-session");
987
g_ptr_array_add (args, "--autostart");
988
g_ptr_array_add (args, DATADIR "/gdm/greeter/autostart");
991
g_ptr_array_add (args, "--debug");
994
if (session_id != NULL) {
995
g_ptr_array_add (args, " --session");
996
g_ptr_array_add (args, (char *) session_id);
999
g_ptr_array_add (args, NULL);
1001
argv = (char **) g_ptr_array_free (args, FALSE);
1002
command = g_strjoinv (" ", argv);
1005
launch_environment = g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT,
1007
"user-name", user_name,
1008
"x11-display-name", display_name,
1009
"x11-display-seat-id", seat_id,
1010
"x11-display-device", display_device,
1011
"x11-display-hostname", display_hostname,
1012
"x11-display-is-local", display_is_local,
1013
"runtime-dir", GDM_SCREENSHOT_DIR,
1017
return launch_environment;
1021
start_launch_environment (GdmSimpleSlave *slave,
1025
gboolean display_is_local;
1029
char *display_device;
1030
char *display_hostname;
1034
g_debug ("GdmSimpleSlave: Running greeter");
1036
display_is_local = FALSE;
1038
display_name = NULL;
1041
display_device = NULL;
1042
display_hostname = NULL;
1044
g_object_get (slave,
1045
"display-id", &display_id,
1046
"display-is-local", &display_is_local,
1047
"display-name", &display_name,
1048
"display-seat-id", &seat_id,
1049
"display-hostname", &display_hostname,
1050
"display-x11-authority-file", &auth_file,
1053
g_debug ("GdmSimpleSlave: Creating greeter for %s %s", display_name, display_hostname);
1055
if (slave->priv->server != NULL) {
1056
display_device = gdm_server_get_display_device (slave->priv->server);
1059
/* FIXME: send a signal back to the master */
1061
/* If XDMCP setup pinging */
1062
slave->priv->ping_interval = DEFAULT_PING_INTERVAL;
1063
res = gdm_settings_direct_get_int (GDM_KEY_PING_INTERVAL,
1064
&(slave->priv->ping_interval));
1066
if ( ! display_is_local && res && slave->priv->ping_interval > 0) {
1067
alarm (slave->priv->ping_interval);
1070
/* Run the init script. gdmslave suspends until script has terminated */
1071
gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
1073
g_debug ("GdmSimpleSlave: Creating greeter on %s %s %s", display_name, display_device, display_hostname);
1074
slave->priv->greeter_environment = create_environment (session_id,
1081
g_signal_connect (slave->priv->greeter_environment,
1083
G_CALLBACK (on_greeter_environment_session_opened),
1085
g_signal_connect (slave->priv->greeter_environment,
1087
G_CALLBACK (on_greeter_environment_session_started),
1089
g_signal_connect (slave->priv->greeter_environment,
1091
G_CALLBACK (on_greeter_environment_session_stopped),
1093
g_signal_connect (slave->priv->greeter_environment,
1095
G_CALLBACK (on_greeter_environment_session_exited),
1097
g_signal_connect (slave->priv->greeter_environment,
1099
G_CALLBACK (on_greeter_environment_session_died),
1101
g_object_set (slave->priv->greeter_environment,
1102
"x11-authority-file", auth_file,
1105
gdm_launch_environment_start (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment));
1107
g_free (display_id);
1108
g_free (display_name);
1110
g_free (display_device);
1111
g_free (display_hostname);
1116
start_greeter (GdmSimpleSlave *slave)
1118
start_launch_environment (slave, GDM_USERNAME, NULL);
1121
#define RULES_DIR LOCALSTATEDIR "/lib/polkit-1/localauthority/10-vendor.d/"
1122
#define RULES_FILE "20-gnome-initial-setup.rules"
1124
static const gboolean
1125
create_initial_setup_user (GdmSimpleSlave *slave)
1127
gboolean ret = TRUE;
1128
ActUserManager *act;
1130
GFile *src_file, *dest_file;
1131
GError *error = NULL;
1132
const char *e = NULL;
1134
/* First, create the user */
1135
act = act_user_manager_get_default ();
1137
user = act_user_manager_create_user (act, INITIAL_SETUP_USERNAME, "", 0, &error);
1139
if (g_dbus_error_is_remote_error (error)) {
1140
e = g_dbus_error_get_remote_error (error);
1143
g_warning ("Creating user '%s' failed: %s / %s",
1144
INITIAL_SETUP_USERNAME, e, error->message);
1146
if (g_strcmp0 (e, "org.freedesktop.Accounts.Error.UserExists") != 0) {
1151
g_object_unref (user);
1154
/* Now, make sure the PolicyKit policy is in place */
1155
src_file = g_file_new_for_path (DATADIR "/gnome-initial-setup" RULES_FILE);
1156
dest_file = g_file_new_for_path (RULES_DIR RULES_FILE);
1158
if (!g_file_copy (src_file,
1160
G_FILE_COPY_OVERWRITE,
1161
NULL, NULL, NULL, &error)) {
1162
g_warning ("Failed to copy '%s' to '%s': %s",
1163
g_file_get_path (src_file),
1164
g_file_get_path (dest_file),
1167
goto out_clear_files;
1171
g_object_unref (src_file);
1172
g_object_unref (dest_file);
1175
g_clear_pointer (&e, g_free);
1176
g_clear_error (&error);
1181
destroy_initial_setup_user (GdmSimpleSlave *slave)
1183
ActUserManager *act;
1185
const char *filename;
1188
filename = RULES_DIR RULES_FILE;
1190
if (g_remove (filename) < 0) {
1191
g_warning ("Failed to remove '%s': %s", filename, g_strerror (errno));
1194
act = act_user_manager_get_default ();
1197
user = act_user_manager_get_user (act, INITIAL_SETUP_USERNAME);
1198
if (!act_user_manager_delete_user (act, user, TRUE, &error)) {
1199
g_warning ("Failed to delete user '%s': %s", INITIAL_SETUP_USERNAME, error->message);
1200
g_error_free (error);
1203
g_object_unref (user);
1207
start_initial_setup (GdmSimpleSlave *slave)
1209
create_initial_setup_user (slave);
1210
start_launch_environment (slave, INITIAL_SETUP_USERNAME, "gnome-initial-setup");
1211
destroy_initial_setup_user (slave);
1215
wants_autologin (GdmSimpleSlave *slave)
1217
gboolean enabled = FALSE;
1219
/* FIXME: handle wait-for-go */
1221
gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay);
1222
return enabled && delay == 0;
1225
#define INITIAL_SETUP_TRIGGER_FILE LOCALSTATEDIR "/lib/gdm/run-initial-setup"
1228
wants_initial_setup (GdmSimpleSlave *slave)
1232
if (!g_file_test (INITIAL_SETUP_TRIGGER_FILE, G_FILE_TEST_EXISTS)) {
1236
if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) {
1248
idle_connect_to_display (GdmSimpleSlave *slave)
1252
slave->priv->connection_attempts++;
1254
res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave));
1256
setup_server (slave);
1258
if (wants_initial_setup (slave)) {
1259
start_initial_setup (slave);
1260
} else if (wants_autologin (slave)) {
1261
/* Run the init script. gdmslave suspends until script has terminated */
1262
gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
1264
start_greeter (slave);
1266
create_new_session (slave);
1268
if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) {
1269
g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts);
1279
on_server_ready (GdmServer *server,
1280
GdmSimpleSlave *slave)
1282
g_idle_add ((GSourceFunc)idle_connect_to_display, slave);
1286
on_server_exited (GdmServer *server,
1288
GdmSimpleSlave *slave)
1290
g_debug ("GdmSimpleSlave: server exited with code %d\n", exit_code);
1292
gdm_slave_stop (GDM_SLAVE (slave));
1294
#ifdef WITH_PLYMOUTH
1295
if (slave->priv->plymouth_is_running) {
1296
plymouth_quit_without_transition (slave);
1302
on_server_died (GdmServer *server,
1304
GdmSimpleSlave *slave)
1306
g_debug ("GdmSimpleSlave: server died with signal %d, (%s)",
1308
g_strsignal (signal_number));
1310
gdm_slave_stop (GDM_SLAVE (slave));
1312
#ifdef WITH_PLYMOUTH
1313
if (slave->priv->plymouth_is_running) {
1314
plymouth_quit_without_transition (slave);
1320
gdm_simple_slave_run (GdmSimpleSlave *slave)
1325
gboolean display_is_local;
1326
gboolean display_is_initial;
1328
g_object_get (slave,
1329
"display-is-local", &display_is_local,
1330
"display-name", &display_name,
1331
"display-seat-id", &seat_id,
1332
"display-x11-authority-file", &auth_file,
1333
"display-is-initial", &display_is_initial,
1336
/* if this is local display start a server if one doesn't
1338
if (display_is_local) {
1340
gboolean disable_tcp;
1342
slave->priv->server = gdm_server_new (display_name, seat_id, auth_file, display_is_initial);
1345
if (gdm_settings_client_get_boolean (GDM_KEY_DISALLOW_TCP,
1347
g_object_set (slave->priv->server,
1348
"disable-tcp", disable_tcp,
1352
g_signal_connect (slave->priv->server,
1354
G_CALLBACK (on_server_exited),
1356
g_signal_connect (slave->priv->server,
1358
G_CALLBACK (on_server_died),
1360
g_signal_connect (slave->priv->server,
1362
G_CALLBACK (on_server_ready),
1365
#ifdef WITH_PLYMOUTH
1366
slave->priv->plymouth_is_running = plymouth_is_running ();
1368
if (slave->priv->plymouth_is_running) {
1369
plymouth_prepare_for_transition (slave);
1372
res = gdm_server_start (slave->priv->server);
1374
g_warning (_("Could not start the X "
1375
"server (your graphical environment) "
1376
"due to an internal error. "
1377
"Please contact your system administrator "
1378
"or check your syslog to diagnose. "
1379
"In the meantime this display will be "
1380
"disabled. Please restart GDM when "
1381
"the problem is corrected."));
1382
#ifdef WITH_PLYMOUTH
1383
if (slave->priv->plymouth_is_running) {
1384
plymouth_quit_without_transition (slave);
1390
g_debug ("GdmSimpleSlave: Started X server");
1392
g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
1395
g_free (display_name);
1402
gdm_simple_slave_open_session (GdmSlave *slave,
1404
uid_t uid_of_caller,
1408
GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
1411
if (self->priv->session_is_running) {
1414
G_DBUS_ERROR_ACCESS_DENIED,
1415
_("Can only be called before user is logged in"));
1419
allowed_user = gdm_session_get_allowed_user (self->priv->session);
1421
if (uid_of_caller != allowed_user) {
1424
G_DBUS_ERROR_ACCESS_DENIED,
1425
_("Caller not GDM"));
1429
*address = gdm_session_get_server_address (self->priv->session);
1435
gdm_simple_slave_open_reauthentication_channel_finish (GdmSlave *slave,
1436
GAsyncResult *result,
1439
GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
1440
const char *address;
1442
g_return_val_if_fail (g_simple_async_result_is_valid (result,
1444
gdm_simple_slave_open_reauthentication_channel), NULL);
1446
address = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
1448
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) {
1452
return g_strdup (address);
1456
gdm_simple_slave_open_reauthentication_channel (GdmSlave *slave,
1457
const char *username,
1459
uid_t uid_of_caller,
1460
GAsyncReadyCallback callback,
1462
GCancellable *cancellable)
1464
GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
1465
GSimpleAsyncResult *result;
1467
result = g_simple_async_result_new (G_OBJECT (slave),
1470
gdm_simple_slave_open_reauthentication_channel);
1472
g_simple_async_result_set_check_cancellable (result, cancellable);
1474
if (!self->priv->session_is_running) {
1475
g_simple_async_result_set_error (result,
1477
G_DBUS_ERROR_ACCESS_DENIED,
1478
_("User not logged in"));
1479
g_simple_async_result_complete_in_idle (result);
1482
g_hash_table_insert (self->priv->open_reauthentication_requests,
1483
GINT_TO_POINTER (pid_of_caller),
1484
g_object_ref (result));
1486
gdm_session_start_reauthentication (self->priv->session,
1491
g_object_unref (result);
1495
gdm_simple_slave_start (GdmSlave *slave)
1497
GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->start (slave);
1499
gdm_simple_slave_run (GDM_SIMPLE_SLAVE (slave));
1505
gdm_simple_slave_stop (GdmSlave *slave)
1507
GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
1509
g_debug ("GdmSimpleSlave: Stopping simple_slave");
1511
GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->stop (slave);
1513
if (self->priv->greeter_environment != NULL) {
1514
stop_greeter (self);
1515
self->priv->greeter_environment = NULL;
1518
if (self->priv->session_is_running) {
1521
/* Run the PostSession script. gdmslave suspends until script
1524
username = gdm_session_get_username (self->priv->session);
1525
if (username != NULL) {
1526
gdm_slave_run_script (slave, GDMCONFDIR "/PostSession", username);
1530
#ifdef HAVE_LOGINDEVPERM
1531
gdm_simple_slave_revoke_console_permissions (self);
1534
self->priv->session_is_running = FALSE;
1537
if (self->priv->session != NULL) {
1538
gdm_session_close (self->priv->session);
1539
g_clear_object (&self->priv->session);
1542
if (self->priv->server != NULL) {
1543
gdm_server_stop (self->priv->server);
1544
g_clear_object (&self->priv->server);
1551
gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass)
1553
GObjectClass *object_class = G_OBJECT_CLASS (klass);
1554
GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass);
1556
object_class->finalize = gdm_simple_slave_finalize;
1558
slave_class->start = gdm_simple_slave_start;
1559
slave_class->stop = gdm_simple_slave_stop;
1560
slave_class->open_session = gdm_simple_slave_open_session;
1561
slave_class->open_reauthentication_channel = gdm_simple_slave_open_reauthentication_channel;
1562
slave_class->open_reauthentication_channel_finish = gdm_simple_slave_open_reauthentication_channel_finish;
1564
g_type_class_add_private (klass, sizeof (GdmSimpleSlavePrivate));
1568
gdm_simple_slave_init (GdmSimpleSlave *slave)
1570
slave->priv = GDM_SIMPLE_SLAVE_GET_PRIVATE (slave);
1571
#ifdef HAVE_LOGINDEVPERM
1572
slave->priv->use_logindevperm = FALSE;
1575
slave->priv->open_reauthentication_requests = g_hash_table_new_full (NULL,
1584
gdm_simple_slave_finalize (GObject *object)
1586
GdmSimpleSlave *slave;
1588
g_return_if_fail (object != NULL);
1589
g_return_if_fail (GDM_IS_SIMPLE_SLAVE (object));
1591
slave = GDM_SIMPLE_SLAVE (object);
1593
g_return_if_fail (slave->priv != NULL);
1595
gdm_slave_stop (GDM_SLAVE (slave));
1597
g_hash_table_unref (slave->priv->open_reauthentication_requests);
1599
if (slave->priv->greeter_reset_id > 0) {
1600
g_source_remove (slave->priv->greeter_reset_id);
1601
slave->priv->greeter_reset_id = 0;
1604
G_OBJECT_CLASS (gdm_simple_slave_parent_class)->finalize (object);
1608
gdm_simple_slave_new (const char *id)
1612
object = g_object_new (GDM_TYPE_SIMPLE_SLAVE,
1616
return GDM_SLAVE (object);