~darkxst/ubuntu/saucy/gdm/lp1212408

« back to all changes in this revision

Viewing changes to .pc/ubuntu_daemon_autologin_tracking.patch/daemon/gdm-simple-slave.c

  • Committer: Package Import Robot
  • Author(s): Tim Lunn
  • Date: 2012-10-07 07:40:28 UTC
  • Revision ID: package-import@ubuntu.com-20121007074028-f2c3v19u9oqxqf9r
Tags: 3.6.0-0ubuntu4
* debian/patches
  - add 3 upstream patches to fix logout when autologin enabled.
    (LP: #1061993)
    - ubuntu_ensure_dirs.patch
    - ubuntu_slave-only-set-up-autologin.patch
    - ubuntu_daemon_autologin_tracking.patch
 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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.
 
18
 *
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#include <stdlib.h>
 
24
#include <stdio.h>
 
25
#include <fcntl.h>
 
26
#include <unistd.h>
 
27
#include <string.h>
 
28
#include <sys/types.h>
 
29
#include <sys/wait.h>
 
30
#include <errno.h>
 
31
 
 
32
#ifdef  HAVE_LOGINDEVPERM
 
33
#include <libdevinfo.h>
 
34
#endif  /* HAVE_LOGINDEVPERM */
 
35
 
 
36
#include <glib.h>
 
37
#include <glib/gi18n.h>
 
38
#include <glib/gstdio.h>
 
39
#include <glib-object.h>
 
40
 
 
41
#include <X11/Xlib.h> /* for Display */
 
42
 
 
43
#include <act/act-user-manager.h>
 
44
 
 
45
#include "gdm-common.h"
 
46
 
 
47
#include "gdm-settings-client.h"
 
48
#include "gdm-settings-keys.h"
 
49
 
 
50
#include "gdm-simple-slave.h"
 
51
 
 
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"
 
58
 
 
59
#define GDM_SIMPLE_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SIMPLE_SLAVE, GdmSimpleSlavePrivate))
 
60
 
 
61
#define GDM_DBUS_NAME              "org.gnome.DisplayManager"
 
62
#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
 
63
 
 
64
#define MAX_CONNECT_ATTEMPTS  10
 
65
#define DEFAULT_PING_INTERVAL 15
 
66
 
 
67
#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
 
68
 
 
69
struct GdmSimpleSlavePrivate
 
70
{
 
71
        GPid               pid;
 
72
        gint               greeter_reset_id;
 
73
        guint              start_session_id;
 
74
 
 
75
        char              *start_session_service_name;
 
76
 
 
77
        int                ping_interval;
 
78
 
 
79
        GPid               server_pid;
 
80
        guint              connection_attempts;
 
81
 
 
82
        GdmServer         *server;
 
83
 
 
84
        /* we control the user session */
 
85
        GdmSession        *session;
 
86
 
 
87
        /* this spawns and controls the greeter session */
 
88
        GdmLaunchEnvironment *greeter_environment;
 
89
 
 
90
        GHashTable        *open_reauthentication_requests;
 
91
 
 
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;
 
97
#endif
 
98
#ifdef  WITH_PLYMOUTH
 
99
        guint              plymouth_is_running : 1;
 
100
#endif
 
101
};
 
102
 
 
103
enum {
 
104
        PROP_0,
 
105
};
 
106
 
 
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,
 
112
                                                                GPid                  pid_of_caller,
 
113
                                                                uid_t                 uid_of_caller,
 
114
                                                                GAsyncReadyCallback   callback,
 
115
                                                                gpointer              user_data,
 
116
                                                                GCancellable         *cancellable);
 
117
 
 
118
G_DEFINE_TYPE (GdmSimpleSlave, gdm_simple_slave, GDM_TYPE_SLAVE)
 
119
 
 
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);
 
124
 
 
125
static void
 
126
on_session_started (GdmSession       *session,
 
127
                    const char       *service_name,
 
128
                    int               pid,
 
129
                    GdmSimpleSlave   *slave)
 
130
{
 
131
        char *username;
 
132
        char *session_id;
 
133
 
 
134
        g_debug ("GdmSimpleSlave: session started %d", pid);
 
135
 
 
136
        slave->priv->session_is_running = TRUE;
 
137
 
 
138
        session_id = gdm_session_get_session_id (session);
 
139
        g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL);
 
140
        g_free (session_id);
 
141
 
 
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);
 
146
        }
 
147
        g_free (username);
 
148
 
 
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)
 
154
         */
 
155
}
 
156
 
 
157
#ifdef  HAVE_LOGINDEVPERM
 
158
static void
 
159
gdm_simple_slave_grant_console_permissions (GdmSimpleSlave *slave)
 
160
{
 
161
        char *username;
 
162
        char *display_device;
 
163
        struct passwd *passwd_entry;
 
164
 
 
165
        username = gdm_session_get_username (slave->priv->session);
 
166
        display_device = gdm_session_get_display_device (slave->priv->session);
 
167
 
 
168
        if (username != NULL) {
 
169
                gdm_get_pwent_for_name (username, &passwd_entry);
 
170
 
 
171
                /*
 
172
                 * Only do logindevperm processing if /dev/console or
 
173
                 * a device associated with a VT
 
174
                 */
 
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,
 
183
                                                 NULL);
 
184
                        slave->priv->use_logindevperm = TRUE;
 
185
                }
 
186
        }
 
187
 
 
188
        if (!slave->priv->use_logindevperm) {
 
189
                g_debug ("Not calling di_devperm_login login for user %s, device %s",
 
190
                         username, display_device);
 
191
        }
 
192
}
 
193
 
 
194
static void
 
195
gdm_simple_slave_revoke_console_permissions (GdmSimpleSlave *slave)
 
196
{
 
197
        char *username;
 
198
        char *display_device;
 
199
 
 
200
        username = gdm_session_get_username (slave->priv->session);
 
201
        display_device = gdm_session_get_display_device (slave->priv->session);
 
202
 
 
203
        /*
 
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.
 
208
         */
 
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;
 
217
        } else {
 
218
                g_debug ("Not calling di_devperm_logout logout for user %s, device %s",
 
219
                         username, display_device);
 
220
        }
 
221
 
 
222
        g_free (username);
 
223
        g_free (display_device);
 
224
}
 
225
#endif  /* HAVE_LOGINDEVPERM */
 
226
 
 
227
static void
 
228
on_session_exited (GdmSession       *session,
 
229
                   int               exit_code,
 
230
                   GdmSimpleSlave   *slave)
 
231
{
 
232
        g_object_set (GDM_SLAVE (slave), "session-id", NULL, NULL);
 
233
 
 
234
        g_debug ("GdmSimpleSlave: session exited with code %d\n", exit_code);
 
235
        gdm_slave_stop (GDM_SLAVE (slave));
 
236
}
 
237
 
 
238
static void
 
239
on_session_died (GdmSession       *session,
 
240
                 int               signal_number,
 
241
                 GdmSimpleSlave   *slave)
 
242
{
 
243
        g_object_set (GDM_SLAVE (slave), "session-id", NULL, NULL);
 
244
 
 
245
        g_debug ("GdmSimpleSlave: session died with signal %d, (%s)",
 
246
                 signal_number,
 
247
                 g_strsignal (signal_number));
 
248
        gdm_slave_stop (GDM_SLAVE (slave));
 
249
}
 
250
 
 
251
static gboolean
 
252
add_user_authorization (GdmSimpleSlave *slave,
 
253
                        char          **filename)
 
254
{
 
255
        char    *username;
 
256
        gboolean ret;
 
257
 
 
258
        username = gdm_session_get_username (slave->priv->session);
 
259
        ret = gdm_slave_add_user_authorization (GDM_SLAVE (slave),
 
260
                                                username,
 
261
                                                filename);
 
262
        g_free (username);
 
263
 
 
264
        return ret;
 
265
}
 
266
 
 
267
static void
 
268
reset_session (GdmSimpleSlave  *slave)
 
269
{
 
270
        if (slave->priv->session == NULL) {
 
271
                return;
 
272
        }
 
273
 
 
274
        gdm_session_reset (slave->priv->session);
 
275
}
 
276
 
 
277
static gboolean
 
278
greeter_reset_timeout (GdmSimpleSlave  *slave)
 
279
{
 
280
        g_debug ("GdmSimpleSlave: resetting greeter");
 
281
 
 
282
        reset_session (slave);
 
283
 
 
284
        slave->priv->greeter_reset_id = 0;
 
285
        return FALSE;
 
286
}
 
287
 
 
288
static void
 
289
queue_greeter_reset (GdmSimpleSlave  *slave)
 
290
{
 
291
        if (slave->priv->greeter_reset_id > 0) {
 
292
                return;
 
293
        }
 
294
 
 
295
        slave->priv->greeter_reset_id = g_idle_add ((GSourceFunc)greeter_reset_timeout, slave);
 
296
}
 
297
 
 
298
static void
 
299
gdm_simple_slave_start_session_when_ready (GdmSimpleSlave *slave,
 
300
                                           const char     *service_name)
 
301
{
 
302
        if (slave->priv->start_session_when_ready) {
 
303
                slave->priv->waiting_to_start_session = FALSE;
 
304
                queue_start_session (slave, service_name);
 
305
        } else {
 
306
                slave->priv->waiting_to_start_session = TRUE;
 
307
        }
 
308
}
 
309
 
 
310
static gboolean
 
311
try_migrate_session (GdmSimpleSlave  *slave)
 
312
{
 
313
        char    *username;
 
314
        gboolean res;
 
315
 
 
316
        g_debug ("GdmSimpleSlave: trying to migrate session");
 
317
 
 
318
        username = gdm_session_get_username (slave->priv->session);
 
319
 
 
320
        /* try to switch to an existing session */
 
321
        res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username);
 
322
        g_free (username);
 
323
 
 
324
        return res;
 
325
}
 
326
 
 
327
static void
 
328
stop_greeter (GdmSimpleSlave *slave)
 
329
{
 
330
        char *username;
 
331
        gboolean script_successful;
 
332
 
 
333
        g_debug ("GdmSimpleSlave: Stopping greeter");
 
334
 
 
335
        if (slave->priv->greeter_environment == NULL) {
 
336
                g_debug ("GdmSimpleSlave: No greeter running");
 
337
                return;
 
338
        }
 
339
 
 
340
        /* Run the PostLogin script. gdmslave suspends until script has terminated */
 
341
        username = NULL;
 
342
        if (slave->priv->session != NULL) {
 
343
                username = gdm_session_get_username (slave->priv->session);
 
344
        }
 
345
 
 
346
        if (username != NULL) {
 
347
                script_successful = gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PostLogin", username);
 
348
        } else {
 
349
                script_successful = TRUE;
 
350
        }
 
351
        g_free (username);
 
352
 
 
353
        if (!script_successful) {
 
354
                g_debug ("GdmSimpleSlave: PostLogin script unsuccessful");
 
355
 
 
356
                slave->priv->start_session_id = 0;
 
357
                queue_greeter_reset (slave);
 
358
                return;
 
359
        }
 
360
 
 
361
        gdm_launch_environment_stop (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment));
 
362
}
 
363
 
 
364
static void
 
365
start_session (GdmSimpleSlave  *slave)
 
366
{
 
367
        char           *auth_file;
 
368
 
 
369
        auth_file = NULL;
 
370
        add_user_authorization (slave, &auth_file);
 
371
 
 
372
        g_assert (auth_file != NULL);
 
373
 
 
374
        g_object_set (slave->priv->session,
 
375
                      "user-x11-authority-file", auth_file,
 
376
                      NULL);
 
377
 
 
378
        g_free (auth_file);
 
379
 
 
380
        gdm_session_start_session (slave->priv->session,
 
381
                                   slave->priv->start_session_service_name);
 
382
 
 
383
        slave->priv->start_session_id = 0;
 
384
        g_free (slave->priv->start_session_service_name);
 
385
        slave->priv->start_session_service_name = NULL;
 
386
}
 
387
 
 
388
static gboolean
 
389
start_session_timeout (GdmSimpleSlave  *slave)
 
390
{
 
391
        gboolean migrated;
 
392
 
 
393
 
 
394
        g_debug ("GdmSimpleSlave: accredited");
 
395
 
 
396
        migrated = try_migrate_session (slave);
 
397
        g_debug ("GdmSimpleSlave: migrated: %d", migrated);
 
398
        if (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
 
402
                   user switching. */
 
403
                gdm_session_reset (slave->priv->session);
 
404
 
 
405
                slave->priv->start_session_id = 0;
 
406
                g_free (slave->priv->start_session_service_name);
 
407
                slave->priv->start_session_service_name = NULL;
 
408
        } else {
 
409
                if (slave->priv->greeter_environment == NULL) {
 
410
                        /* auto login */
 
411
                        start_session (slave);
 
412
                } else {
 
413
                        /* Session actually gets started from on_greeter_environment_session_stop */
 
414
                        stop_greeter (slave);
 
415
                }
 
416
        }
 
417
 
 
418
        return FALSE;
 
419
}
 
420
 
 
421
static void
 
422
queue_start_session (GdmSimpleSlave *slave,
 
423
                     const char     *service_name)
 
424
{
 
425
        if (slave->priv->start_session_id > 0) {
 
426
                return;
 
427
        }
 
428
 
 
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);
 
431
}
 
432
 
 
433
static void
 
434
on_session_reauthenticated (GdmSession       *session,
 
435
                            const char       *service_name,
 
436
                            GdmSimpleSlave   *slave)
 
437
{
 
438
        try_migrate_session (slave);
 
439
}
 
440
 
 
441
static void
 
442
on_session_opened (GdmSession       *session,
 
443
                   const char       *service_name,
 
444
                   const char       *session_id,
 
445
                   GdmSimpleSlave   *slave)
 
446
{
 
447
 
 
448
#ifdef  HAVE_LOGINDEVPERM
 
449
        gdm_simple_slave_grant_console_permissions (slave);
 
450
#endif  /* HAVE_LOGINDEVPERM */
 
451
 
 
452
        if (gdm_session_client_is_connected (slave->priv->session)) {
 
453
                gdm_simple_slave_start_session_when_ready (slave, service_name);
 
454
        } else {
 
455
                /* Auto login */
 
456
                slave->priv->start_session_when_ready = TRUE;
 
457
                gdm_simple_slave_start_session_when_ready (slave, service_name);
 
458
        }
 
459
}
 
460
 
 
461
static void
 
462
on_session_conversation_started (GdmSession       *session,
 
463
                                 const char       *service_name,
 
464
                                 GdmSimpleSlave   *slave)
 
465
{
 
466
        gboolean enabled;
 
467
        char    *username;
 
468
        int      delay;
 
469
 
 
470
        g_debug ("GdmSimpleSlave: session conversation started for service %s", service_name);
 
471
 
 
472
        if (g_strcmp0 (service_name, "gdm-autologin") != 0) {
 
473
                return;
 
474
        }
 
475
 
 
476
        enabled = FALSE;
 
477
        gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, &username, &delay);
 
478
        if (! enabled) {
 
479
                return;
 
480
        }
 
481
 
 
482
        if (delay == 0) {
 
483
                g_debug ("GdmSimpleSlave: begin auto login for user '%s'", username);
 
484
                /* service_name will be "gdm-autologin"
 
485
                 */
 
486
                gdm_session_setup_for_user (slave->priv->session, service_name, username);
 
487
        }
 
488
 
 
489
        g_free (username);
 
490
}
 
491
 
 
492
static void
 
493
on_session_conversation_stopped (GdmSession       *session,
 
494
                                 const char       *service_name,
 
495
                                 GdmSimpleSlave   *slave)
 
496
{
 
497
        g_debug ("GdmSimpleSlave: conversation stopped");
 
498
 
 
499
}
 
500
 
 
501
static void
 
502
start_autologin_conversation_if_necessary (GdmSimpleSlave  *slave)
 
503
{
 
504
        gboolean enabled;
 
505
 
 
506
        gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, NULL);
 
507
 
 
508
        if (!enabled) {
 
509
                return;
 
510
        }
 
511
 
 
512
        g_debug ("GdmSimpleSlave: Starting automatic login conversation");
 
513
        gdm_session_start_conversation (slave->priv->session, "gdm-autologin");
 
514
}
 
515
 
 
516
static void
 
517
on_session_reauthentication_started (GdmSession      *session,
 
518
                                     int              pid_of_caller,
 
519
                                     const char      *address,
 
520
                                     GdmSimpleSlave  *slave)
 
521
{
 
522
        GSimpleAsyncResult *result;
 
523
        gpointer            source_tag;
 
524
 
 
525
        g_debug ("GdmSimpleSlave: reauthentication started");
 
526
 
 
527
        source_tag = GINT_TO_POINTER (pid_of_caller);
 
528
 
 
529
        result = g_hash_table_lookup (slave->priv->open_reauthentication_requests,
 
530
                                      source_tag);
 
531
 
 
532
        if (result != NULL) {
 
533
                g_simple_async_result_set_op_res_gpointer (result,
 
534
                                                           g_strdup (address),
 
535
                                                           (GDestroyNotify)
 
536
                                                           g_free);
 
537
                g_simple_async_result_complete_in_idle (result);
 
538
        }
 
539
 
 
540
        g_hash_table_remove (slave->priv->open_reauthentication_requests,
 
541
                             source_tag);
 
542
}
 
543
 
 
544
static void
 
545
on_session_client_ready_for_session_to_start (GdmSession      *session,
 
546
                                              const char      *service_name,
 
547
                                              gboolean         client_is_ready,
 
548
                                              GdmSimpleSlave  *slave)
 
549
{
 
550
        if (client_is_ready) {
 
551
                g_debug ("GdmSimpleSlave: Will start session when ready");
 
552
        } else {
 
553
                g_debug ("GdmSimpleSlave: Will start session when ready and told");
 
554
        }
 
555
 
 
556
        if (slave->priv->greeter_reset_id > 0) {
 
557
                return;
 
558
        }
 
559
 
 
560
        slave->priv->start_session_when_ready = client_is_ready;
 
561
 
 
562
        if (client_is_ready && slave->priv->waiting_to_start_session) {
 
563
                gdm_simple_slave_start_session_when_ready (slave, service_name);
 
564
        }
 
565
}
 
566
 
 
567
static void
 
568
on_ready_to_request_timed_login (GdmSession         *session,
 
569
                                 GSimpleAsyncResult *result,
 
570
                                 gpointer           *user_data)
 
571
{
 
572
        int delay = GPOINTER_TO_INT (user_data);
 
573
        GCancellable *cancellable;
 
574
        char         *username;
 
575
 
 
576
        cancellable = g_object_get_data (G_OBJECT (result),
 
577
                                         "cancellable");
 
578
        if (g_cancellable_is_cancelled (cancellable)) {
 
579
                return;
 
580
        }
 
581
 
 
582
        username = g_simple_async_result_get_source_tag (result);
 
583
 
 
584
        gdm_session_request_timed_login (session, username, delay);
 
585
 
 
586
        g_object_weak_unref (G_OBJECT (session),
 
587
                             (GWeakNotify)
 
588
                             g_cancellable_cancel,
 
589
                             cancellable);
 
590
        g_object_weak_unref (G_OBJECT (session),
 
591
                             (GWeakNotify)
 
592
                             g_object_unref,
 
593
                             cancellable);
 
594
        g_object_weak_unref (G_OBJECT (session),
 
595
                             (GWeakNotify)
 
596
                             g_free,
 
597
                             username);
 
598
 
 
599
        g_free (username);
 
600
}
 
601
 
 
602
static gboolean
 
603
on_wait_for_greeter_timeout (GSimpleAsyncResult *result)
 
604
{
 
605
        g_simple_async_result_complete (result);
 
606
 
 
607
        return FALSE;
 
608
}
 
609
 
 
610
static void
 
611
on_session_client_connected (GdmSession          *session,
 
612
                             GCredentials        *credentials,
 
613
                             GPid                 pid_of_client,
 
614
                             GdmSimpleSlave      *slave)
 
615
{
 
616
        gboolean timed_login_enabled;
 
617
        char    *username;
 
618
        int      delay;
 
619
        gboolean display_is_local;
 
620
 
 
621
        g_debug ("GdmSimpleSlave: client connected");
 
622
 
 
623
        g_object_get (slave,
 
624
                      "display-is-local", &display_is_local,
 
625
                      NULL);
 
626
 
 
627
        /* If XDMCP stop pinging */
 
628
        if ( ! display_is_local) {
 
629
                alarm (0);
 
630
        }
 
631
 
 
632
        timed_login_enabled = FALSE;
 
633
        gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &timed_login_enabled, &username, &delay);
 
634
 
 
635
        if (! timed_login_enabled) {
 
636
                return;
 
637
        }
 
638
 
 
639
        /* temporary hack to fix timed login
 
640
         * http://bugzilla.gnome.org/680348
 
641
         */
 
642
        if (delay > 0) {
 
643
                GSimpleAsyncResult *result;
 
644
                GCancellable       *cancellable;
 
645
                guint               timeout_id;
 
646
                gpointer            source_tag;
 
647
 
 
648
                delay = MAX (delay, 4);
 
649
 
 
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),
 
656
                                                    source_tag);
 
657
                g_simple_async_result_set_check_cancellable (result, cancellable);
 
658
                g_object_set_data (G_OBJECT (result),
 
659
                                   "cancellable",
 
660
                                   cancellable);
 
661
 
 
662
                timeout_id = g_timeout_add_seconds_full (delay - 2,
 
663
                                                         G_PRIORITY_DEFAULT,
 
664
                                                         (GSourceFunc)
 
665
                                                         on_wait_for_greeter_timeout,
 
666
                                                         g_object_ref (result),
 
667
                                                         (GDestroyNotify)
 
668
                                                         g_object_unref);
 
669
                g_cancellable_connect (cancellable,
 
670
                                       G_CALLBACK (g_source_remove),
 
671
                                       GINT_TO_POINTER (timeout_id),
 
672
                                       NULL);
 
673
 
 
674
                g_object_weak_ref (G_OBJECT (session),
 
675
                                   (GWeakNotify)
 
676
                                   g_cancellable_cancel,
 
677
                                   cancellable);
 
678
                g_object_weak_ref (G_OBJECT (session),
 
679
                                   (GWeakNotify)
 
680
                                   g_object_unref,
 
681
                                   cancellable);
 
682
                g_object_weak_ref (G_OBJECT (session),
 
683
                                   (GWeakNotify)
 
684
                                   g_free,
 
685
                                   source_tag);
 
686
        }
 
687
 
 
688
        g_free (username);
 
689
}
 
690
 
 
691
static void
 
692
on_session_client_disconnected (GdmSession          *session,
 
693
                                GCredentials        *credentials,
 
694
                                GPid                 pid_of_client,
 
695
                                GdmSimpleSlave      *slave)
 
696
{
 
697
        gboolean display_is_local;
 
698
 
 
699
        g_debug ("GdmSimpleSlave: client disconnected");
 
700
 
 
701
        g_object_get (slave,
 
702
                      "display-is-local", &display_is_local,
 
703
                      NULL);
 
704
 
 
705
        if ( ! display_is_local && !slave->priv->session_is_running) {
 
706
                gdm_slave_stop (GDM_SLAVE (slave));
 
707
        }
 
708
}
 
709
 
 
710
static void
 
711
on_session_cancelled (GdmSession      *session,
 
712
                      GdmSimpleSlave  *slave)
 
713
{
 
714
        g_debug ("GdmSimpleSlave: Session was cancelled");
 
715
        queue_greeter_reset (slave);
 
716
}
 
717
 
 
718
static void
 
719
create_new_session (GdmSimpleSlave  *slave)
 
720
{
 
721
        gboolean       display_is_local;
 
722
        char          *display_id;
 
723
        char          *display_name;
 
724
        char          *display_hostname;
 
725
        char          *display_device;
 
726
        char          *display_seat_id;
 
727
        char          *display_x11_authority_file;
 
728
        GdmSession    *greeter_session;
 
729
        uid_t          greeter_uid;
 
730
 
 
731
        g_debug ("GdmSimpleSlave: Creating new session");
 
732
 
 
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);
 
736
        } else {
 
737
                greeter_uid = 0;
 
738
        }
 
739
 
 
740
        g_object_get (slave,
 
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,
 
747
                      NULL);
 
748
 
 
749
        display_device = NULL;
 
750
        if (slave->priv->server != NULL) {
 
751
                display_device = gdm_server_get_display_device (slave->priv->server);
 
752
        }
 
753
 
 
754
        slave->priv->session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN,
 
755
                                                greeter_uid,
 
756
                                                display_name,
 
757
                                                display_hostname,
 
758
                                                display_device,
 
759
                                                display_seat_id,
 
760
                                                display_x11_authority_file,
 
761
                                                display_is_local,
 
762
                                                NULL);
 
763
 
 
764
        g_free (display_id);
 
765
        g_free (display_name);
 
766
        g_free (display_device);
 
767
        g_free (display_hostname);
 
768
 
 
769
        g_signal_connect (slave->priv->session,
 
770
                          "reauthentication-started",
 
771
                          G_CALLBACK (on_session_reauthentication_started),
 
772
                          slave);
 
773
        g_signal_connect (slave->priv->session,
 
774
                          "reauthenticated",
 
775
                          G_CALLBACK (on_session_reauthenticated),
 
776
                          slave);
 
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),
 
780
                          slave);
 
781
        g_signal_connect (slave->priv->session,
 
782
                          "client-connected",
 
783
                          G_CALLBACK (on_session_client_connected),
 
784
                          slave);
 
785
        g_signal_connect (slave->priv->session,
 
786
                          "client-disconnected",
 
787
                          G_CALLBACK (on_session_client_disconnected),
 
788
                          slave);
 
789
        g_signal_connect (slave->priv->session,
 
790
                          "cancelled",
 
791
                          G_CALLBACK (on_session_cancelled),
 
792
                          slave);
 
793
        g_signal_connect (slave->priv->session,
 
794
                          "conversation-started",
 
795
                          G_CALLBACK (on_session_conversation_started),
 
796
                          slave);
 
797
        g_signal_connect (slave->priv->session,
 
798
                          "conversation-stopped",
 
799
                          G_CALLBACK (on_session_conversation_stopped),
 
800
                          slave);
 
801
        g_signal_connect (slave->priv->session,
 
802
                          "session-opened",
 
803
                          G_CALLBACK (on_session_opened),
 
804
                          slave);
 
805
        g_signal_connect (slave->priv->session,
 
806
                          "session-started",
 
807
                          G_CALLBACK (on_session_started),
 
808
                          slave);
 
809
        g_signal_connect (slave->priv->session,
 
810
                          "session-exited",
 
811
                          G_CALLBACK (on_session_exited),
 
812
                          slave);
 
813
        g_signal_connect (slave->priv->session,
 
814
                          "session-died",
 
815
                          G_CALLBACK (on_session_died),
 
816
                          slave);
 
817
 
 
818
        start_autologin_conversation_if_necessary (slave);
 
819
}
 
820
 
 
821
static void
 
822
on_greeter_environment_session_opened (GdmLaunchEnvironment *greeter_environment,
 
823
                                       GdmSimpleSlave       *slave)
 
824
{
 
825
        char       *session_id;
 
826
 
 
827
        g_debug ("GdmSimpleSlave: Greeter session opened");
 
828
        session_id = gdm_launch_environment_get_session_id (GDM_LAUNCH_ENVIRONMENT (greeter_environment));
 
829
 
 
830
        g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL);
 
831
        g_free (session_id);
 
832
}
 
833
 
 
834
static void
 
835
on_greeter_environment_session_started (GdmLaunchEnvironment *greeter_environment,
 
836
                                        GdmSimpleSlave       *slave)
 
837
{
 
838
        g_debug ("GdmSimpleSlave: Greeter started");
 
839
}
 
840
 
 
841
static void
 
842
on_greeter_environment_session_stopped (GdmLaunchEnvironment *greeter_environment,
 
843
                                        GdmSimpleSlave       *slave)
 
844
{
 
845
        g_debug ("GdmSimpleSlave: Greeter stopped");
 
846
        if (slave->priv->start_session_service_name == NULL) {
 
847
                gdm_slave_stop (GDM_SLAVE (slave));
 
848
        } else {
 
849
                start_session (slave);
 
850
        }
 
851
 
 
852
        g_object_unref (slave->priv->greeter_environment);
 
853
        slave->priv->greeter_environment = NULL;
 
854
}
 
855
 
 
856
static void
 
857
on_greeter_environment_session_exited (GdmLaunchEnvironment    *greeter_environment,
 
858
                                       int                      code,
 
859
                                       GdmSimpleSlave          *slave)
 
860
{
 
861
        g_debug ("GdmSimpleSlave: Greeter exited: %d", code);
 
862
        if (slave->priv->start_session_service_name == NULL) {
 
863
                gdm_slave_stop (GDM_SLAVE (slave));
 
864
        }
 
865
}
 
866
 
 
867
static void
 
868
on_greeter_environment_session_died (GdmLaunchEnvironment    *greeter_environment,
 
869
                                     int                      signal,
 
870
                                     GdmSimpleSlave          *slave)
 
871
{
 
872
        g_debug ("GdmSimpleSlave: Greeter died: %d", signal);
 
873
        if (slave->priv->start_session_service_name == NULL) {
 
874
                gdm_slave_stop (GDM_SLAVE (slave));
 
875
        }
 
876
}
 
877
 
 
878
#ifdef  WITH_PLYMOUTH
 
879
static gboolean
 
880
plymouth_is_running (void)
 
881
{
 
882
        int      status;
 
883
        gboolean res;
 
884
        GError  *error;
 
885
 
 
886
        error = NULL;
 
887
        res = g_spawn_command_line_sync ("/bin/plymouth --ping",
 
888
                                         NULL, NULL, &status, &error);
 
889
        if (! res) {
 
890
                g_debug ("Could not ping plymouth: %s", error->message);
 
891
                g_error_free (error);
 
892
                return FALSE;
 
893
        }
 
894
 
 
895
        return WIFEXITED (status) && WEXITSTATUS (status) == 0;
 
896
}
 
897
 
 
898
static void
 
899
plymouth_prepare_for_transition (GdmSimpleSlave *slave)
 
900
{
 
901
        gboolean res;
 
902
        GError  *error;
 
903
 
 
904
        error = NULL;
 
905
        res = g_spawn_command_line_sync ("/bin/plymouth deactivate",
 
906
                                         NULL, NULL, NULL, &error);
 
907
        if (! res) {
 
908
                g_warning ("Could not deactivate plymouth: %s", error->message);
 
909
                g_error_free (error);
 
910
        }
 
911
}
 
912
 
 
913
static void
 
914
plymouth_quit_with_transition (GdmSimpleSlave *slave)
 
915
{
 
916
        gboolean res;
 
917
        GError  *error;
 
918
 
 
919
        error = NULL;
 
920
        res = g_spawn_command_line_sync ("/bin/plymouth quit --retain-splash",
 
921
                                         NULL, NULL, NULL, &error);
 
922
        if (! res) {
 
923
                g_warning ("Could not quit plymouth: %s", error->message);
 
924
                g_error_free (error);
 
925
        }
 
926
        slave->priv->plymouth_is_running = FALSE;
 
927
}
 
928
 
 
929
static void
 
930
plymouth_quit_without_transition (GdmSimpleSlave *slave)
 
931
{
 
932
        gboolean res;
 
933
        GError  *error;
 
934
 
 
935
        error = NULL;
 
936
        res = g_spawn_command_line_sync ("/bin/plymouth quit",
 
937
                                         NULL, NULL, NULL, &error);
 
938
        if (! res) {
 
939
                g_warning ("Could not quit plymouth: %s", error->message);
 
940
                g_error_free (error);
 
941
        }
 
942
        slave->priv->plymouth_is_running = FALSE;
 
943
}
 
944
#endif
 
945
 
 
946
static void
 
947
setup_server (GdmSimpleSlave *slave)
 
948
{
 
949
        /* Put cursor out of the way on first head */
 
950
        gdm_slave_set_initial_cursor_position (GDM_SLAVE (slave));
 
951
 
 
952
        /* Set the busy cursor */
 
953
        gdm_slave_set_busy_cursor (GDM_SLAVE (slave));
 
954
 
 
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.
 
960
         */
 
961
        gdm_slave_save_root_windows (GDM_SLAVE (slave));
 
962
 
 
963
#ifdef WITH_PLYMOUTH
 
964
        /* Plymouth is waiting for the go-ahead to exit */
 
965
        if (slave->priv->plymouth_is_running) {
 
966
                plymouth_quit_with_transition (slave);
 
967
        }
 
968
#endif
 
969
}
 
970
 
 
971
static GdmLaunchEnvironment *
 
972
create_environment (const char *session_id,
 
973
                    const char *user_name,
 
974
                    const char *display_name,
 
975
                    const char *seat_id,
 
976
                    const char *display_device,
 
977
                    const char *display_hostname,
 
978
                    gboolean    display_is_local)
 
979
{
 
980
        gboolean debug = FALSE;
 
981
        char *command;
 
982
        GdmLaunchEnvironment *launch_environment;
 
983
        char **argv;
 
984
        GPtrArray *args;
 
985
 
 
986
        gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug);
 
987
 
 
988
        args = g_ptr_array_new ();
 
989
        g_ptr_array_add (args, BINDIR "/gnome-session");
 
990
 
 
991
        g_ptr_array_add (args, "--autostart");
 
992
        g_ptr_array_add (args, DATADIR "/gdm/greeter/autostart");
 
993
 
 
994
        if (debug) {
 
995
                g_ptr_array_add (args, "--debug");
 
996
        }
 
997
 
 
998
        if (session_id != NULL) {
 
999
                g_ptr_array_add (args, " --session");
 
1000
                g_ptr_array_add (args, (char *) session_id);
 
1001
        }
 
1002
 
 
1003
        g_ptr_array_add (args, NULL);
 
1004
 
 
1005
        argv = (char **) g_ptr_array_free (args, FALSE);
 
1006
        command = g_strjoinv (" ", argv);
 
1007
        g_free (argv);
 
1008
 
 
1009
        launch_environment = g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT,
 
1010
                                           "command", command,
 
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,
 
1018
                                           NULL);
 
1019
 
 
1020
        g_free (command);
 
1021
        return launch_environment;
 
1022
}
 
1023
 
 
1024
static void
 
1025
start_launch_environment (GdmSimpleSlave *slave,
 
1026
                          char           *username,
 
1027
                          char           *session_id)
 
1028
{
 
1029
        gboolean       display_is_local;
 
1030
        char          *display_id;
 
1031
        char          *display_name;
 
1032
        char          *seat_id;
 
1033
        char          *display_device;
 
1034
        char          *display_hostname;
 
1035
        char          *auth_file;
 
1036
        gboolean       res;
 
1037
 
 
1038
        g_debug ("GdmSimpleSlave: Running greeter");
 
1039
 
 
1040
        display_is_local = FALSE;
 
1041
        display_id = NULL;
 
1042
        display_name = NULL;
 
1043
        seat_id = NULL;
 
1044
        auth_file = NULL;
 
1045
        display_device = NULL;
 
1046
        display_hostname = NULL;
 
1047
 
 
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,
 
1055
                      NULL);
 
1056
 
 
1057
        g_debug ("GdmSimpleSlave: Creating greeter for %s %s", display_name, display_hostname);
 
1058
 
 
1059
        if (slave->priv->server != NULL) {
 
1060
                display_device = gdm_server_get_display_device (slave->priv->server);
 
1061
        }
 
1062
 
 
1063
        /* FIXME: send a signal back to the master */
 
1064
 
 
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));
 
1069
 
 
1070
        if ( ! display_is_local && res && slave->priv->ping_interval > 0) {
 
1071
                alarm (slave->priv->ping_interval);
 
1072
        }
 
1073
 
 
1074
        /* Run the init script. gdmslave suspends until script has terminated */
 
1075
        gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
 
1076
 
 
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,
 
1079
                                                               username,
 
1080
                                                               display_name,
 
1081
                                                               seat_id,
 
1082
                                                               display_device,
 
1083
                                                               display_hostname,
 
1084
                                                               display_is_local);
 
1085
        g_signal_connect (slave->priv->greeter_environment,
 
1086
                          "opened",
 
1087
                          G_CALLBACK (on_greeter_environment_session_opened),
 
1088
                          slave);
 
1089
        g_signal_connect (slave->priv->greeter_environment,
 
1090
                          "started",
 
1091
                          G_CALLBACK (on_greeter_environment_session_started),
 
1092
                          slave);
 
1093
        g_signal_connect (slave->priv->greeter_environment,
 
1094
                          "stopped",
 
1095
                          G_CALLBACK (on_greeter_environment_session_stopped),
 
1096
                          slave);
 
1097
        g_signal_connect (slave->priv->greeter_environment,
 
1098
                          "exited",
 
1099
                          G_CALLBACK (on_greeter_environment_session_exited),
 
1100
                          slave);
 
1101
        g_signal_connect (slave->priv->greeter_environment,
 
1102
                          "died",
 
1103
                          G_CALLBACK (on_greeter_environment_session_died),
 
1104
                          slave);
 
1105
        g_object_set (slave->priv->greeter_environment,
 
1106
                      "x11-authority-file", auth_file,
 
1107
                      NULL);
 
1108
 
 
1109
        gdm_launch_environment_start (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment));
 
1110
 
 
1111
        g_free (display_id);
 
1112
        g_free (display_name);
 
1113
        g_free (seat_id);
 
1114
        g_free (display_device);
 
1115
        g_free (display_hostname);
 
1116
        g_free (auth_file);
 
1117
}
 
1118
 
 
1119
static void
 
1120
start_greeter (GdmSimpleSlave *slave)
 
1121
{
 
1122
        start_launch_environment (slave, GDM_USERNAME, NULL);
 
1123
}
 
1124
 
 
1125
#define RULES_DIR LOCALSTATEDIR "/lib/polkit-1/localauthority/10-vendor.d/"
 
1126
#define RULES_FILE "20-gnome-initial-setup.rules"
 
1127
 
 
1128
static const gboolean
 
1129
create_initial_setup_user (GdmSimpleSlave *slave)
 
1130
{
 
1131
        gboolean ret = TRUE;
 
1132
        ActUserManager *act;
 
1133
        ActUser *user;
 
1134
        GFile *src_file, *dest_file;
 
1135
        GError *error = NULL;
 
1136
        const char *e = NULL;
 
1137
 
 
1138
        /* First, create the user */
 
1139
        act = act_user_manager_get_default ();
 
1140
 
 
1141
        user = act_user_manager_create_user (act, INITIAL_SETUP_USERNAME, "", 0, &error);
 
1142
        if (user == NULL) {
 
1143
                if (g_dbus_error_is_remote_error (error)) {
 
1144
                        e = g_dbus_error_get_remote_error (error);
 
1145
                }
 
1146
 
 
1147
                g_warning ("Creating user '%s' failed: %s / %s",
 
1148
                           INITIAL_SETUP_USERNAME, e, error->message);
 
1149
 
 
1150
                if (g_strcmp0 (e, "org.freedesktop.Accounts.Error.UserExists") != 0) {
 
1151
                        ret = FALSE;
 
1152
                        goto out;
 
1153
                }
 
1154
        } else {
 
1155
                g_object_unref (user);
 
1156
        }
 
1157
 
 
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);
 
1161
 
 
1162
        if (!g_file_copy (src_file,
 
1163
                          dest_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),
 
1169
                           error->message);
 
1170
                ret = FALSE;
 
1171
                goto out_clear_files;
 
1172
        }
 
1173
 
 
1174
 out_clear_files:
 
1175
        g_object_unref (src_file);
 
1176
        g_object_unref (dest_file);
 
1177
 
 
1178
 out:
 
1179
        g_clear_pointer (&e, g_free);
 
1180
        g_clear_error (&error);
 
1181
        return ret;
 
1182
}
 
1183
 
 
1184
static void
 
1185
destroy_initial_setup_user (GdmSimpleSlave *slave)
 
1186
{
 
1187
        ActUserManager *act;
 
1188
        ActUser *user;
 
1189
        const char *filename;
 
1190
        GError *error;
 
1191
 
 
1192
        filename = RULES_DIR RULES_FILE;
 
1193
 
 
1194
        if (g_remove (filename) < 0) {
 
1195
                g_warning ("Failed to remove '%s': %s", filename, g_strerror (errno));
 
1196
        }
 
1197
 
 
1198
        act = act_user_manager_get_default ();
 
1199
 
 
1200
        error = NULL;
 
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);
 
1205
        }
 
1206
 
 
1207
        g_object_unref (user);
 
1208
}
 
1209
 
 
1210
static void
 
1211
start_initial_setup (GdmSimpleSlave *slave)
 
1212
{
 
1213
        create_initial_setup_user (slave);
 
1214
        start_launch_environment (slave, INITIAL_SETUP_USERNAME, "gnome-initial-setup");
 
1215
        destroy_initial_setup_user (slave);
 
1216
}
 
1217
 
 
1218
static gboolean
 
1219
wants_autologin (GdmSimpleSlave *slave)
 
1220
{
 
1221
        gboolean enabled = FALSE;
 
1222
        int delay = 0;
 
1223
        /* FIXME: handle wait-for-go */
 
1224
 
 
1225
        gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay);
 
1226
        return enabled && delay == 0;
 
1227
}
 
1228
 
 
1229
#define INITIAL_SETUP_TRIGGER_FILE LOCALSTATEDIR "/lib/gdm/run-initial-setup"
 
1230
 
 
1231
static gboolean
 
1232
wants_initial_setup (GdmSimpleSlave *slave)
 
1233
{
 
1234
        gboolean enabled;
 
1235
 
 
1236
        if (!g_file_test (INITIAL_SETUP_TRIGGER_FILE, G_FILE_TEST_EXISTS)) {
 
1237
                return FALSE;
 
1238
        }
 
1239
 
 
1240
        if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) {
 
1241
                return FALSE;
 
1242
        }
 
1243
 
 
1244
        if (!enabled) {
 
1245
                return FALSE;
 
1246
        }
 
1247
 
 
1248
        return TRUE;
 
1249
}
 
1250
 
 
1251
static gboolean
 
1252
idle_connect_to_display (GdmSimpleSlave *slave)
 
1253
{
 
1254
        gboolean res;
 
1255
 
 
1256
        slave->priv->connection_attempts++;
 
1257
 
 
1258
        res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave));
 
1259
        if (res) {
 
1260
                setup_server (slave);
 
1261
 
 
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);
 
1267
                } else {
 
1268
                        start_greeter (slave);
 
1269
                }
 
1270
                create_new_session (slave);
 
1271
        } else {
 
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);
 
1274
                        exit (1);
 
1275
                }
 
1276
                return TRUE;
 
1277
        }
 
1278
 
 
1279
        return FALSE;
 
1280
}
 
1281
 
 
1282
static void
 
1283
on_server_ready (GdmServer      *server,
 
1284
                 GdmSimpleSlave *slave)
 
1285
{
 
1286
        g_idle_add ((GSourceFunc)idle_connect_to_display, slave);
 
1287
}
 
1288
 
 
1289
static void
 
1290
on_server_exited (GdmServer      *server,
 
1291
                  int             exit_code,
 
1292
                  GdmSimpleSlave *slave)
 
1293
{
 
1294
        g_debug ("GdmSimpleSlave: server exited with code %d\n", exit_code);
 
1295
 
 
1296
        gdm_slave_stop (GDM_SLAVE (slave));
 
1297
 
 
1298
#ifdef WITH_PLYMOUTH
 
1299
        if (slave->priv->plymouth_is_running) {
 
1300
                plymouth_quit_without_transition (slave);
 
1301
        }
 
1302
#endif
 
1303
}
 
1304
 
 
1305
static void
 
1306
on_server_died (GdmServer      *server,
 
1307
                int             signal_number,
 
1308
                GdmSimpleSlave *slave)
 
1309
{
 
1310
        g_debug ("GdmSimpleSlave: server died with signal %d, (%s)",
 
1311
                 signal_number,
 
1312
                 g_strsignal (signal_number));
 
1313
 
 
1314
        gdm_slave_stop (GDM_SLAVE (slave));
 
1315
 
 
1316
#ifdef WITH_PLYMOUTH
 
1317
        if (slave->priv->plymouth_is_running) {
 
1318
                plymouth_quit_without_transition (slave);
 
1319
        }
 
1320
#endif
 
1321
}
 
1322
 
 
1323
static gboolean
 
1324
gdm_simple_slave_run (GdmSimpleSlave *slave)
 
1325
{
 
1326
        char    *display_name;
 
1327
        char    *auth_file;
 
1328
        char    *seat_id;
 
1329
        gboolean display_is_local;
 
1330
        gboolean display_is_initial;
 
1331
 
 
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,
 
1338
                      NULL);
 
1339
 
 
1340
        /* if this is local display start a server if one doesn't
 
1341
         * exist */
 
1342
        if (display_is_local) {
 
1343
                gboolean res;
 
1344
                gboolean disable_tcp;
 
1345
 
 
1346
                slave->priv->server = gdm_server_new (display_name, seat_id, auth_file, display_is_initial);
 
1347
 
 
1348
                disable_tcp = TRUE;
 
1349
                if (gdm_settings_client_get_boolean (GDM_KEY_DISALLOW_TCP,
 
1350
                                                     &disable_tcp)) {
 
1351
                        g_object_set (slave->priv->server,
 
1352
                                      "disable-tcp", disable_tcp,
 
1353
                                      NULL);
 
1354
                }
 
1355
 
 
1356
                g_signal_connect (slave->priv->server,
 
1357
                                  "exited",
 
1358
                                  G_CALLBACK (on_server_exited),
 
1359
                                  slave);
 
1360
                g_signal_connect (slave->priv->server,
 
1361
                                  "died",
 
1362
                                  G_CALLBACK (on_server_died),
 
1363
                                  slave);
 
1364
                g_signal_connect (slave->priv->server,
 
1365
                                  "ready",
 
1366
                                  G_CALLBACK (on_server_ready),
 
1367
                                  slave);
 
1368
 
 
1369
#ifdef WITH_PLYMOUTH
 
1370
                slave->priv->plymouth_is_running = plymouth_is_running ();
 
1371
 
 
1372
                if (slave->priv->plymouth_is_running) {
 
1373
                        plymouth_prepare_for_transition (slave);
 
1374
                }
 
1375
#endif
 
1376
                res = gdm_server_start (slave->priv->server);
 
1377
                if (! res) {
 
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);
 
1389
                        }
 
1390
#endif
 
1391
                        exit (1);
 
1392
                }
 
1393
 
 
1394
                g_debug ("GdmSimpleSlave: Started X server");
 
1395
        } else {
 
1396
                g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
 
1397
        }
 
1398
 
 
1399
        g_free (display_name);
 
1400
        g_free (auth_file);
 
1401
 
 
1402
        return TRUE;
 
1403
}
 
1404
 
 
1405
static gboolean
 
1406
gdm_simple_slave_open_session (GdmSlave  *slave,
 
1407
                               GPid       pid_of_caller,
 
1408
                               uid_t      uid_of_caller,
 
1409
                               char     **address,
 
1410
                               GError   **error)
 
1411
{
 
1412
        GdmSimpleSlave     *self = GDM_SIMPLE_SLAVE (slave);
 
1413
        uid_t               allowed_user;
 
1414
 
 
1415
        if (self->priv->session_is_running) {
 
1416
                g_set_error (error,
 
1417
                             G_DBUS_ERROR,
 
1418
                             G_DBUS_ERROR_ACCESS_DENIED,
 
1419
                             _("Can only be called before user is logged in"));
 
1420
                return FALSE;
 
1421
        }
 
1422
 
 
1423
        allowed_user = gdm_session_get_allowed_user (self->priv->session);
 
1424
 
 
1425
        if (uid_of_caller != allowed_user) {
 
1426
                g_set_error (error,
 
1427
                             G_DBUS_ERROR,
 
1428
                             G_DBUS_ERROR_ACCESS_DENIED,
 
1429
                             _("Caller not GDM"));
 
1430
                return FALSE;
 
1431
        }
 
1432
 
 
1433
        *address = gdm_session_get_server_address (self->priv->session);
 
1434
 
 
1435
        return TRUE;
 
1436
}
 
1437
 
 
1438
static char *
 
1439
gdm_simple_slave_open_reauthentication_channel_finish (GdmSlave      *slave,
 
1440
                                                       GAsyncResult  *result,
 
1441
                                                       GError       **error)
 
1442
{
 
1443
        GdmSimpleSlave  *self = GDM_SIMPLE_SLAVE (slave);
 
1444
        const char      *address;
 
1445
 
 
1446
        g_return_val_if_fail (g_simple_async_result_is_valid (result,
 
1447
                                                              G_OBJECT (self),
 
1448
                                                              gdm_simple_slave_open_reauthentication_channel), NULL);
 
1449
 
 
1450
        address = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
 
1451
 
 
1452
        if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) {
 
1453
                return NULL;
 
1454
        }
 
1455
 
 
1456
        return g_strdup (address);
 
1457
}
 
1458
 
 
1459
static void
 
1460
gdm_simple_slave_open_reauthentication_channel (GdmSlave             *slave,
 
1461
                                                const char           *username,
 
1462
                                                GPid                  pid_of_caller,
 
1463
                                                uid_t                 uid_of_caller,
 
1464
                                                GAsyncReadyCallback   callback,
 
1465
                                                gpointer              user_data,
 
1466
                                                GCancellable         *cancellable)
 
1467
{
 
1468
        GdmSimpleSlave     *self = GDM_SIMPLE_SLAVE (slave);
 
1469
        GSimpleAsyncResult *result;
 
1470
 
 
1471
        result = g_simple_async_result_new (G_OBJECT (slave),
 
1472
                                            callback,
 
1473
                                            user_data,
 
1474
                                            gdm_simple_slave_open_reauthentication_channel);
 
1475
 
 
1476
        g_simple_async_result_set_check_cancellable (result, cancellable);
 
1477
 
 
1478
        if (!self->priv->session_is_running) {
 
1479
                g_simple_async_result_set_error (result,
 
1480
                                                 G_DBUS_ERROR,
 
1481
                                                 G_DBUS_ERROR_ACCESS_DENIED,
 
1482
                                                 _("User not logged in"));
 
1483
                g_simple_async_result_complete_in_idle (result);
 
1484
 
 
1485
        } else {
 
1486
                g_hash_table_insert (self->priv->open_reauthentication_requests,
 
1487
                                     GINT_TO_POINTER (pid_of_caller),
 
1488
                                     g_object_ref (result));
 
1489
 
 
1490
                gdm_session_start_reauthentication (self->priv->session,
 
1491
                                                    pid_of_caller,
 
1492
                                                    uid_of_caller);
 
1493
        }
 
1494
 
 
1495
        g_object_unref (result);
 
1496
}
 
1497
 
 
1498
static gboolean
 
1499
gdm_simple_slave_start (GdmSlave *slave)
 
1500
{
 
1501
        GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->start (slave);
 
1502
 
 
1503
        gdm_simple_slave_run (GDM_SIMPLE_SLAVE (slave));
 
1504
 
 
1505
        return TRUE;
 
1506
}
 
1507
 
 
1508
static gboolean
 
1509
gdm_simple_slave_stop (GdmSlave *slave)
 
1510
{
 
1511
        GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave);
 
1512
 
 
1513
        g_debug ("GdmSimpleSlave: Stopping simple_slave");
 
1514
 
 
1515
        GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->stop (slave);
 
1516
 
 
1517
        if (self->priv->greeter_environment != NULL) {
 
1518
                stop_greeter (self);
 
1519
                self->priv->greeter_environment = NULL;
 
1520
        }
 
1521
 
 
1522
        if (self->priv->session_is_running) {
 
1523
                char *username;
 
1524
 
 
1525
                /* Run the PostSession script. gdmslave suspends until script
 
1526
                 * has terminated
 
1527
                 */
 
1528
                username = gdm_session_get_username (self->priv->session);
 
1529
                if (username != NULL) {
 
1530
                        gdm_slave_run_script (slave, GDMCONFDIR "/PostSession", username);
 
1531
                }
 
1532
                g_free (username);
 
1533
 
 
1534
#ifdef  HAVE_LOGINDEVPERM
 
1535
                gdm_simple_slave_revoke_console_permissions (self);
 
1536
#endif
 
1537
 
 
1538
                self->priv->session_is_running = FALSE;
 
1539
        }
 
1540
 
 
1541
        if (self->priv->session != NULL) {
 
1542
                gdm_session_close (self->priv->session);
 
1543
                g_clear_object (&self->priv->session);
 
1544
        }
 
1545
 
 
1546
        if (self->priv->server != NULL) {
 
1547
                gdm_server_stop (self->priv->server);
 
1548
                g_clear_object (&self->priv->server);
 
1549
        }
 
1550
 
 
1551
        return TRUE;
 
1552
}
 
1553
 
 
1554
static void
 
1555
gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass)
 
1556
{
 
1557
        GObjectClass  *object_class = G_OBJECT_CLASS (klass);
 
1558
        GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass);
 
1559
 
 
1560
        object_class->finalize = gdm_simple_slave_finalize;
 
1561
 
 
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;
 
1567
 
 
1568
        g_type_class_add_private (klass, sizeof (GdmSimpleSlavePrivate));
 
1569
}
 
1570
 
 
1571
static void
 
1572
gdm_simple_slave_init (GdmSimpleSlave *slave)
 
1573
{
 
1574
        slave->priv = GDM_SIMPLE_SLAVE_GET_PRIVATE (slave);
 
1575
#ifdef  HAVE_LOGINDEVPERM
 
1576
        slave->priv->use_logindevperm = FALSE;
 
1577
#endif
 
1578
 
 
1579
        slave->priv->open_reauthentication_requests = g_hash_table_new_full (NULL,
 
1580
                                                                             NULL,
 
1581
                                                                             (GDestroyNotify)
 
1582
                                                                             NULL,
 
1583
                                                                             (GDestroyNotify)
 
1584
                                                                             g_object_unref);
 
1585
}
 
1586
 
 
1587
static void
 
1588
gdm_simple_slave_finalize (GObject *object)
 
1589
{
 
1590
        GdmSimpleSlave *slave;
 
1591
 
 
1592
        g_return_if_fail (object != NULL);
 
1593
        g_return_if_fail (GDM_IS_SIMPLE_SLAVE (object));
 
1594
 
 
1595
        slave = GDM_SIMPLE_SLAVE (object);
 
1596
 
 
1597
        g_return_if_fail (slave->priv != NULL);
 
1598
 
 
1599
        gdm_slave_stop (GDM_SLAVE (slave));
 
1600
 
 
1601
        g_hash_table_unref (slave->priv->open_reauthentication_requests);
 
1602
 
 
1603
        if (slave->priv->greeter_reset_id > 0) {
 
1604
                g_source_remove (slave->priv->greeter_reset_id);
 
1605
                slave->priv->greeter_reset_id = 0;
 
1606
        }
 
1607
 
 
1608
        G_OBJECT_CLASS (gdm_simple_slave_parent_class)->finalize (object);
 
1609
}
 
1610
 
 
1611
GdmSlave *
 
1612
gdm_simple_slave_new (const char *id)
 
1613
{
 
1614
        GObject *object;
 
1615
 
 
1616
        object = g_object_new (GDM_TYPE_SIMPLE_SLAVE,
 
1617
                               "display-id", id,
 
1618
                               NULL);
 
1619
 
 
1620
        return GDM_SLAVE (object);
 
1621
}