source: proiecte/PPPP/gdm/daemon/gdm-simple-slave.c @ 134

Last change on this file since 134 was 134, checked in by (none), 14 years ago

gdm sources with the modifications for webcam

File size: 42.2 KB
Line 
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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#include <glib.h>
33#include <glib/gi18n.h>
34#include <glib/gstdio.h>
35#include <glib-object.h>
36
37#define DBUS_API_SUBJECT_TO_CHANGE
38#include <dbus/dbus-glib.h>
39#include <dbus/dbus-glib-lowlevel.h>
40
41#include <X11/Xlib.h> /* for Display */
42
43#include "gdm-common.h"
44
45#include "gdm-settings-client.h"
46#include "gdm-settings-keys.h"
47
48#include "gdm-simple-slave.h"
49#include "gdm-simple-slave-glue.h"
50
51#include "gdm-server.h"
52#include "gdm-session.h"
53#include "gdm-session-direct.h"
54#include "gdm-greeter-server.h"
55#include "gdm-greeter-session.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
67struct GdmSimpleSlavePrivate
68{
69        GPid               pid;
70
71        guint              greeter_reset_id;
72        guint              start_session_id;
73
74        int                ping_interval;
75
76        GPid               server_pid;
77        guint              connection_attempts;
78
79        GdmServer         *server;
80        GdmSessionDirect  *session;
81
82        GdmGreeterServer  *greeter_server;
83        GdmGreeterSession *greeter;
84
85        guint              start_session_when_ready : 1;
86        guint              waiting_to_start_session : 1;
87};
88
89enum {
90        PROP_0,
91};
92
93static void     gdm_simple_slave_class_init     (GdmSimpleSlaveClass *klass);
94static void     gdm_simple_slave_init           (GdmSimpleSlave      *simple_slave);
95static void     gdm_simple_slave_finalize       (GObject             *object);
96
97G_DEFINE_TYPE (GdmSimpleSlave, gdm_simple_slave, GDM_TYPE_SLAVE)
98
99static void create_new_session (GdmSimpleSlave *slave);
100static void start_greeter      (GdmSimpleSlave *slave);
101
102static void
103on_session_started (GdmSession       *session,
104                    int               pid,
105                    GdmSimpleSlave   *slave)
106{
107        char *username;
108
109        g_debug ("GdmSimpleSlave: session started %d", pid);
110
111        /* Run the PreSession script. gdmslave suspends until script has terminated */
112        username = gdm_session_direct_get_username (slave->priv->session);
113        gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PreSession", username);
114
115        /* FIXME: should we do something here? */
116}
117
118static void
119on_session_exited (GdmSession     *session,
120                   int             exit_code,
121                   GdmSimpleSlave *slave)
122{
123        char *username;
124
125        g_debug ("GdmSimpleSlave: session exited with code %d\n", exit_code);
126
127        /* Run the PostSession script. gdmslave suspends until script has terminated */
128        username = gdm_session_direct_get_username (slave->priv->session);
129        gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PostSession", username);
130
131        gdm_slave_stopped (GDM_SLAVE (slave));
132}
133
134static void
135on_session_died (GdmSession     *session,
136                 int             signal_number,
137                 GdmSimpleSlave *slave)
138{
139        g_debug ("GdmSimpleSlave: session died with signal %d, (%s)",
140                 signal_number,
141                 g_strsignal (signal_number));
142
143        gdm_slave_stopped (GDM_SLAVE (slave));
144}
145
146static gboolean
147add_user_authorization (GdmSimpleSlave *slave,
148                        char          **filename)
149{
150        char    *username;
151        gboolean ret;
152
153        username = gdm_session_direct_get_username (slave->priv->session);
154        ret = gdm_slave_add_user_authorization (GDM_SLAVE (slave),
155                                                username,
156                                                filename);
157        g_free (username);
158
159        return ret;
160}
161
162static void
163destroy_session (GdmSimpleSlave *slave)
164{
165        if (slave->priv->session != NULL) {
166                gdm_session_close (GDM_SESSION (slave->priv->session));
167                g_object_unref (slave->priv->session);
168                slave->priv->session = NULL;
169        }
170}
171
172static void
173reset_session (GdmSimpleSlave *slave)
174{
175        destroy_session (slave);
176        create_new_session (slave);
177        gdm_session_open (GDM_SESSION (slave->priv->session));
178}
179
180static gboolean
181greeter_reset_timeout (GdmSimpleSlave *slave)
182{
183        g_debug ("GdmSimpleSlave: resetting greeter");
184
185        if (slave->priv->greeter_server != NULL) {
186                gdm_greeter_server_reset (slave->priv->greeter_server);
187                reset_session (slave);
188        } else {
189                start_greeter (slave);
190                create_new_session (slave);
191        }
192        slave->priv->greeter_reset_id = 0;
193        return FALSE;
194}
195
196static void
197queue_greeter_reset (GdmSimpleSlave *slave)
198{
199        if (slave->priv->greeter_reset_id > 0) {
200                return;
201        }
202
203        slave->priv->greeter_reset_id = g_timeout_add_seconds (2, (GSourceFunc)greeter_reset_timeout, slave);
204}
205
206static void
207on_session_setup_complete (GdmSession     *session,
208                           GdmSimpleSlave *slave)
209{
210        gdm_session_authenticate (session);
211}
212
213static void
214on_session_setup_failed (GdmSession     *session,
215                         const char     *message,
216                         GdmSimpleSlave *slave)
217{
218        if (slave->priv->greeter_server != NULL) {
219                gdm_greeter_server_problem (slave->priv->greeter_server,
220                                           message != NULL ? message:  _("Unable to initialize login system"));
221        }
222
223        destroy_session (slave);
224        queue_greeter_reset (slave);
225}
226
227static void
228on_session_reset_complete (GdmSession     *session,
229                           GdmSimpleSlave *slave)
230{
231        g_debug ("GdmSimpleSlave: PAM reset");
232}
233
234static void
235on_session_reset_failed (GdmSession     *session,
236                         const char     *message,
237                         GdmSimpleSlave *slave)
238{
239        g_critical ("Unable to reset PAM");
240}
241
242static void
243on_session_authenticated (GdmSession     *session,
244                          GdmSimpleSlave *slave)
245{
246        gdm_session_authorize (session);
247}
248
249static void
250on_session_authentication_failed (GdmSession     *session,
251                                  const char     *message,
252                                  GdmSimpleSlave *slave)
253{
254        if (slave->priv->greeter_server != NULL) {
255                gdm_greeter_server_problem (slave->priv->greeter_server,
256                                            message != NULL ? message : _("Unable to authenticate user"));
257        }
258        destroy_session (slave);
259        queue_greeter_reset (slave);
260}
261
262static void
263gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave)
264{
265        if (slave->priv->start_session_when_ready) {
266                char *ssid;
267                char *username;
268                int   cred_flag;
269
270                slave->priv->waiting_to_start_session = FALSE;
271
272                username = gdm_session_direct_get_username (slave->priv->session);
273
274                ssid = gdm_slave_get_primary_session_id_for_user (GDM_SLAVE (slave), username);
275                if (ssid != NULL && ssid [0] != '\0') {
276                        /* FIXME: we don't yet support refresh */
277                        cred_flag = GDM_SESSION_CRED_ESTABLISH;
278                } else {
279                        cred_flag = GDM_SESSION_CRED_ESTABLISH;
280                }
281                g_free (ssid);
282                g_free (username);
283
284                gdm_session_accredit (GDM_SESSION (slave->priv->session), cred_flag);
285        } else {
286                slave->priv->waiting_to_start_session = TRUE;
287        }
288}
289
290static void
291on_session_authorized (GdmSession     *session,
292                       GdmSimpleSlave *slave)
293{
294        if (slave->priv->greeter_server != NULL) {
295                gdm_greeter_server_user_authorized (slave->priv->greeter_server);
296                gdm_simple_slave_accredit_when_ready (slave);
297        } else {
298                slave->priv->start_session_when_ready = TRUE;
299                gdm_simple_slave_accredit_when_ready (slave);
300        }
301}
302
303static void
304on_session_authorization_failed (GdmSession     *session,
305                                 const char     *message,
306                                 GdmSimpleSlave *slave)
307{
308        if (slave->priv->greeter_server != NULL) {
309                gdm_greeter_server_problem (slave->priv->greeter_server,
310                                           message != NULL ? message :  _("Unable to authorize user"));
311        }
312
313        destroy_session (slave);
314        queue_greeter_reset (slave);
315}
316
317static gboolean
318try_migrate_session (GdmSimpleSlave *slave)
319{
320        char    *username;
321        gboolean res;
322
323        g_debug ("GdmSimpleSlave: trying to migrate session");
324
325        username = gdm_session_direct_get_username (slave->priv->session);
326
327        /* try to switch to an existing session */
328        res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username);
329        g_free (username);
330
331        return res;
332}
333
334static void
335stop_greeter (GdmSimpleSlave *slave)
336{
337        g_debug ("GdmSimpleSlave: Stopping greeter");
338
339        if (slave->priv->greeter == NULL) {
340                g_debug ("GdmSimpleSlave: No greeter running");
341                return;
342        }
343
344        /* Run the PostLogin script. gdmslave suspends until script has terminated */
345        gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PostLogin", GDM_USERNAME);
346
347        gdm_welcome_session_stop (GDM_WELCOME_SESSION (slave->priv->greeter));
348        gdm_greeter_server_stop (slave->priv->greeter_server);
349
350        g_object_unref (slave->priv->greeter);
351        slave->priv->greeter = NULL;
352}
353
354static gboolean
355start_session_timeout (GdmSimpleSlave *slave)
356{
357
358        char    *auth_file;
359        gboolean migrated;
360
361        g_debug ("GdmSimpleSlave: accredited");
362
363        migrated = try_migrate_session (slave);
364        g_debug ("GdmSimpleSlave: migrated: %d", migrated);
365        if (migrated) {
366                destroy_session (slave);
367
368                /* We don't stop the slave here because
369                   when Xorg exits it switches to the VT it was
370                   started from.  That interferes with fast
371                   user switching. */
372                queue_greeter_reset (slave);
373
374                goto out;
375        }
376
377        stop_greeter (slave);
378
379        auth_file = NULL;
380        add_user_authorization (slave, &auth_file);
381
382        g_assert (auth_file != NULL);
383
384        g_object_set (slave->priv->session,
385                      "user-x11-authority-file", auth_file,
386                      NULL);
387
388        g_free (auth_file);
389
390        gdm_session_start_session (GDM_SESSION (slave->priv->session));
391 out:
392        slave->priv->start_session_id = 0;
393        return FALSE;
394}
395
396static void
397queue_start_session (GdmSimpleSlave *slave)
398{
399        if (slave->priv->start_session_id > 0) {
400                return;
401        }
402
403        slave->priv->start_session_id = g_idle_add ((GSourceFunc)start_session_timeout, slave);
404}
405
406static void
407on_session_accredited (GdmSession     *session,
408                       GdmSimpleSlave *slave)
409{
410        queue_start_session (slave);
411}
412
413static void
414on_session_accreditation_failed (GdmSession     *session,
415                                 const char     *message,
416                                 GdmSimpleSlave *slave)
417{
418        gboolean migrated;
419
420        g_debug ("GdmSimpleSlave: accreditation failed");
421
422        migrated = try_migrate_session (slave);
423
424        /* If we switched to another session we don't care if
425           accreditation fails */
426        if (! migrated) {
427                if (slave->priv->greeter_server != NULL) {
428                        const char *problem;
429                        if (message) {
430                                problem = message;
431                        } else {
432                                problem = _("Unable to establish credentials");
433                        }
434                        gdm_greeter_server_problem (slave->priv->greeter_server,
435                                                    problem);
436                }
437        }
438
439        /* We don't stop the slave here after migrating because
440           when Xorg exits it switches to the VT it was
441           started from.  That interferes with fast
442           user switching. */
443        destroy_session (slave);
444
445        queue_greeter_reset (slave);
446}
447
448static void
449on_session_info (GdmSession     *session,
450                 const char     *text,
451                 GdmSimpleSlave *slave)
452{
453        g_debug ("GdmSimpleSlave: Info: %s", text);
454        if (slave->priv->greeter_server != NULL) {
455                gdm_greeter_server_info (slave->priv->greeter_server, text);
456        }
457}
458
459static void
460on_session_problem (GdmSession     *session,
461                    const char     *text,
462                    GdmSimpleSlave *slave)
463{
464        g_debug ("GdmSimpleSlave: Problem: %s", text);
465        gdm_greeter_server_problem (slave->priv->greeter_server, text);
466}
467
468static void
469on_session_info_query (GdmSession     *session,
470                       const char     *text,
471                       GdmSimpleSlave *slave)
472{
473
474        g_debug ("GdmSimpleSlave: Info query: %s", text);
475        gdm_greeter_server_info_query (slave->priv->greeter_server, text);
476}
477
478static void
479on_session_secret_info_query (GdmSession     *session,
480                              const char     *text,
481                              GdmSimpleSlave *slave)
482{
483        g_debug ("GdmSimpleSlave: Secret info query: %s", text);
484        gdm_greeter_server_secret_info_query (slave->priv->greeter_server, text);
485}
486
487static void
488on_session_opened (GdmSession     *session,
489                   GdmSimpleSlave *slave)
490{
491        gboolean res;
492        gboolean enabled;
493        char    *username;
494        int      delay;
495
496        g_debug ("GdmSimpleSlave: session opened");
497        if (slave->priv->greeter_server != NULL) {
498                res = gdm_greeter_server_ready (slave->priv->greeter_server);
499                if (! res) {
500                        g_warning ("Unable to send ready");
501                }
502        }
503
504        enabled = FALSE;
505        gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, &username, &delay);
506        if (! enabled) {
507                return;
508        }
509
510        if (slave->priv->greeter_server != NULL) {
511                gdm_greeter_server_request_timed_login (slave->priv->greeter_server, username, delay);
512        } else {
513                g_debug ("GdmSimpleSlave: begin auto login for user '%s'", username);
514                gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
515                                            "gdm-autologin",
516                                            username);
517        }
518
519        g_free (username);
520}
521
522static void
523on_session_selected_user_changed (GdmSession     *session,
524                                  const char     *text,
525                                  GdmSimpleSlave *slave)
526{
527        g_debug ("GdmSimpleSlave: Selected user changed: %s", text);
528
529        if (slave->priv->greeter_server != NULL) {
530                gdm_greeter_server_selected_user_changed (slave->priv->greeter_server, text);
531        }
532}
533
534static void
535on_default_language_name_changed (GdmSession     *session,
536                                  const char     *text,
537                                  GdmSimpleSlave *slave)
538{
539        g_debug ("GdmSimpleSlave: Default language name changed: %s", text);
540
541        if (slave->priv->greeter_server != NULL) {
542                gdm_greeter_server_default_language_name_changed (slave->priv->greeter_server, text);
543        }
544}
545
546static void
547on_default_layout_name_changed (GdmSession     *session,
548                                const char     *text,
549                                GdmSimpleSlave *slave)
550{
551        g_debug ("GdmSimpleSlave: Default layout name changed: %s", text);
552
553        if (slave->priv->greeter_server != NULL) {
554                gdm_greeter_server_default_layout_name_changed (slave->priv->greeter_server, text);
555        }
556}
557
558static void
559on_default_session_name_changed (GdmSession     *session,
560                                 const char     *text,
561                                 GdmSimpleSlave *slave)
562{
563        g_debug ("GdmSimpleSlave: Default session name changed: %s", text);
564
565        if (slave->priv->greeter_server != NULL) {
566                gdm_greeter_server_default_session_name_changed (slave->priv->greeter_server, text);
567        }
568}
569
570static void
571create_new_session (GdmSimpleSlave *slave)
572{
573        gboolean       display_is_local;
574        char          *display_id;
575        char          *display_name;
576        char          *display_hostname;
577        char          *display_device;
578        char          *display_x11_authority_file;
579
580        g_debug ("GdmSimpleSlave: Creating new session");
581
582        g_object_get (slave,
583                      "display-id", &display_id,
584                      "display-name", &display_name,
585                      "display-hostname", &display_hostname,
586                      "display-is-local", &display_is_local,
587                      "display-x11-authority-file", &display_x11_authority_file,
588                      NULL);
589
590        display_device = NULL;
591        if (slave->priv->server != NULL) {
592                display_device = gdm_server_get_display_device (slave->priv->server);
593        }
594
595        slave->priv->session = gdm_session_direct_new (display_id,
596                                                       display_name,
597                                                       display_hostname,
598                                                       display_device,
599                                                       display_x11_authority_file,
600                                                       display_is_local);
601        g_free (display_id);
602        g_free (display_name);
603        g_free (display_device);
604        g_free (display_hostname);
605
606        g_signal_connect (slave->priv->session,
607                          "opened",
608                          G_CALLBACK (on_session_opened),
609                          slave);
610        g_signal_connect (slave->priv->session,
611                          "setup-complete",
612                          G_CALLBACK (on_session_setup_complete),
613                          slave);
614        g_signal_connect (slave->priv->session,
615                          "setup-failed",
616                          G_CALLBACK (on_session_setup_failed),
617                          slave);
618        g_signal_connect (slave->priv->session,
619                          "reset-complete",
620                          G_CALLBACK (on_session_reset_complete),
621                          slave);
622        g_signal_connect (slave->priv->session,
623                          "reset-failed",
624                          G_CALLBACK (on_session_reset_failed),
625                          slave);
626        g_signal_connect (slave->priv->session,
627                          "authenticated",
628                          G_CALLBACK (on_session_authenticated),
629                          slave);
630        g_signal_connect (slave->priv->session,
631                          "authentication-failed",
632                          G_CALLBACK (on_session_authentication_failed),
633                          slave);
634        g_signal_connect (slave->priv->session,
635                          "authorized",
636                          G_CALLBACK (on_session_authorized),
637                          slave);
638        g_signal_connect (slave->priv->session,
639                          "authorization-failed",
640                          G_CALLBACK (on_session_authorization_failed),
641                          slave);
642        g_signal_connect (slave->priv->session,
643                          "accredited",
644                          G_CALLBACK (on_session_accredited),
645                          slave);
646        g_signal_connect (slave->priv->session,
647                          "accreditation-failed",
648                          G_CALLBACK (on_session_accreditation_failed),
649                          slave);
650        g_signal_connect (slave->priv->session,
651                          "info",
652                          G_CALLBACK (on_session_info),
653                          slave);
654        g_signal_connect (slave->priv->session,
655                          "problem",
656                          G_CALLBACK (on_session_problem),
657                          slave);
658        g_signal_connect (slave->priv->session,
659                          "info-query",
660                          G_CALLBACK (on_session_info_query),
661                          slave);
662        g_signal_connect (slave->priv->session,
663                          "secret-info-query",
664                          G_CALLBACK (on_session_secret_info_query),
665                          slave);
666        g_signal_connect (slave->priv->session,
667                          "session-started",
668                          G_CALLBACK (on_session_started),
669                          slave);
670        g_signal_connect (slave->priv->session,
671                          "session-exited",
672                          G_CALLBACK (on_session_exited),
673                          slave);
674        g_signal_connect (slave->priv->session,
675                          "session-died",
676                          G_CALLBACK (on_session_died),
677                          slave);
678#if 0
679        g_signal_connect (slave->priv->session,
680                          "closed",
681                          G_CALLBACK (on_session_closed),
682                          slave);
683#endif
684        g_signal_connect (slave->priv->session,
685                          "selected-user-changed",
686                          G_CALLBACK (on_session_selected_user_changed),
687                          slave);
688
689        g_signal_connect (slave->priv->session,
690                          "default-language-name-changed",
691                          G_CALLBACK (on_default_language_name_changed),
692                          slave);
693
694        g_signal_connect (slave->priv->session,
695                          "default-layout-name-changed",
696                          G_CALLBACK (on_default_layout_name_changed),
697                          slave);
698
699        g_signal_connect (slave->priv->session,
700                          "default-session-name-changed",
701                          G_CALLBACK (on_default_session_name_changed),
702                          slave);
703}
704
705static void
706on_greeter_session_start (GdmGreeterSession *greeter,
707                          GdmSimpleSlave    *slave)
708{
709        g_debug ("GdmSimpleSlave: Greeter started");
710}
711
712static void
713on_greeter_session_stop (GdmGreeterSession *greeter,
714                         GdmSimpleSlave    *slave)
715{
716        g_debug ("GdmSimpleSlave: Greeter stopped");
717        gdm_slave_stopped (GDM_SLAVE (slave));
718}
719
720static void
721on_greeter_session_exited (GdmGreeterSession    *greeter,
722                           int                   code,
723                           GdmSimpleSlave       *slave)
724{
725        g_debug ("GdmSimpleSlave: Greeter exited: %d", code);
726        gdm_slave_stopped (GDM_SLAVE (slave));
727}
728
729static void
730on_greeter_session_died (GdmGreeterSession    *greeter,
731                         int                   signal,
732                         GdmSimpleSlave       *slave)
733{
734        g_debug ("GdmSimpleSlave: Greeter died: %d", signal);
735        gdm_slave_stopped (GDM_SLAVE (slave));
736}
737
738static void
739on_greeter_begin_verification (GdmGreeterServer *greeter_server,
740                               GdmSimpleSlave   *slave)
741{
742        g_debug ("GdmSimpleSlave: begin verification");
743        gdm_session_setup (GDM_SESSION (slave->priv->session),
744                           "gdm");
745}
746
747static void
748on_greeter_begin_auto_login (GdmGreeterServer *greeter_server,
749                             const char       *username,
750                             GdmSimpleSlave   *slave)
751{
752        g_debug ("GdmSimpleSlave: begin auto login for user '%s'", username);
753        gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
754                                    "gdm-autologin",
755                                    username);
756}
757
758static void
759on_greeter_begin_verification_for_user (GdmGreeterServer *greeter_server,
760                                        const char       *username,
761                                        GdmSimpleSlave   *slave)
762{
763        g_debug ("GdmSimpleSlave: begin verification");
764        gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
765                                    "gdm",
766                                    username);
767}
768
769static void
770on_greeter_answer (GdmGreeterServer *greeter_server,
771                   const char       *text,
772                   GdmSimpleSlave   *slave)
773{
774        gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
775}
776
777static void
778on_greeter_session_selected (GdmGreeterServer *greeter_server,
779                             const char       *text,
780                             GdmSimpleSlave   *slave)
781{
782        gdm_session_select_session (GDM_SESSION (slave->priv->session), text);
783}
784
785static void
786on_greeter_language_selected (GdmGreeterServer *greeter_server,
787                              const char       *text,
788                              GdmSimpleSlave   *slave)
789{
790        gdm_session_select_language (GDM_SESSION (slave->priv->session), text);
791}
792
793static void
794on_greeter_layout_selected (GdmGreeterServer *greeter_server,
795                            const char       *text,
796                            GdmSimpleSlave   *slave)
797{
798        gdm_session_select_layout (GDM_SESSION (slave->priv->session), text);
799}
800
801static void
802on_greeter_user_selected (GdmGreeterServer *greeter_server,
803                          const char       *text,
804                          GdmSimpleSlave   *slave)
805{
806        g_debug ("GdmSimpleSlave: Greeter user selected");
807}
808
809static void
810on_greeter_cancel (GdmGreeterServer *greeter_server,
811                   GdmSimpleSlave   *slave)
812{
813        g_debug ("GdmSimpleSlave: Greeter cancelled");
814        reset_session (slave);
815}
816
817static void
818on_greeter_connected (GdmGreeterServer *greeter_server,
819                      GdmSimpleSlave   *slave)
820{
821        gboolean display_is_local;
822
823        g_debug ("GdmSimpleSlave: Greeter connected");
824
825        gdm_session_open (GDM_SESSION (slave->priv->session));
826
827        g_object_get (slave,
828                      "display-is-local", &display_is_local,
829                      NULL);
830
831        /* If XDMCP stop pinging */
832        if ( ! display_is_local) {
833                alarm (0);
834        }
835}
836
837static void
838on_start_session_when_ready (GdmGreeterServer *session,
839                             GdmSimpleSlave   *slave)
840{
841        g_debug ("GdmSimpleSlave: Will start session when ready");
842        slave->priv->start_session_when_ready = TRUE;
843
844        if (slave->priv->waiting_to_start_session) {
845                gdm_simple_slave_accredit_when_ready (slave);
846        }
847}
848
849static void
850on_start_session_later (GdmGreeterServer *session,
851                        GdmSimpleSlave   *slave)
852{
853        g_debug ("GdmSimpleSlave: Will start session when ready and told");
854        slave->priv->start_session_when_ready = FALSE;
855}
856
857static void
858setup_server (GdmSimpleSlave *slave)
859{
860        /* Set the busy cursor */
861        gdm_slave_set_busy_cursor (GDM_SLAVE (slave));
862}
863
864static void
865start_greeter (GdmSimpleSlave *slave)
866{
867        gboolean       display_is_local;
868        char          *display_id;
869        char          *display_name;
870        char          *display_device;
871        char          *display_hostname;
872        char          *auth_file;
873        char          *address;
874        gboolean       res;
875
876        g_debug ("GdmSimpleSlave: Running greeter");
877
878        display_is_local = FALSE;
879        display_id = NULL;
880        display_name = NULL;
881        auth_file = NULL;
882        display_device = NULL;
883        display_hostname = NULL;
884
885        g_object_get (slave,
886                      "display-id", &display_id,
887                      "display-is-local", &display_is_local,
888                      "display-name", &display_name,
889                      "display-hostname", &display_hostname,
890                      "display-x11-authority-file", &auth_file,
891                      NULL);
892
893        g_debug ("GdmSimpleSlave: Creating greeter for %s %s", display_name, display_hostname);
894
895        if (slave->priv->server != NULL) {
896                display_device = gdm_server_get_display_device (slave->priv->server);
897        }
898
899        /* FIXME: send a signal back to the master */
900
901        /* If XDMCP setup pinging */
902        slave->priv->ping_interval = DEFAULT_PING_INTERVAL;
903        res = gdm_settings_direct_get_int (GDM_KEY_PING_INTERVAL,
904                                           &(slave->priv->ping_interval));
905
906        if ( ! display_is_local && slave->priv->ping_interval > 0) {
907                alarm (slave->priv->ping_interval);
908        }
909
910        /* Run the init script. gdmslave suspends until script has terminated */
911        gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
912
913        slave->priv->greeter_server = gdm_greeter_server_new (display_id);
914        g_signal_connect (slave->priv->greeter_server,
915                          "begin-auto-login",
916                          G_CALLBACK (on_greeter_begin_auto_login),
917                          slave);
918        g_signal_connect (slave->priv->greeter_server,
919                          "begin-verification",
920                          G_CALLBACK (on_greeter_begin_verification),
921                          slave);
922        g_signal_connect (slave->priv->greeter_server,
923                          "begin-verification-for-user",
924                          G_CALLBACK (on_greeter_begin_verification_for_user),
925                          slave);
926        g_signal_connect (slave->priv->greeter_server,
927                          "query-answer",
928                          G_CALLBACK (on_greeter_answer),
929                          slave);
930        g_signal_connect (slave->priv->greeter_server,
931                          "session-selected",
932                          G_CALLBACK (on_greeter_session_selected),
933                          slave);
934        g_signal_connect (slave->priv->greeter_server,
935                          "language-selected",
936                          G_CALLBACK (on_greeter_language_selected),
937                          slave);
938        g_signal_connect (slave->priv->greeter_server,
939                          "layout-selected",
940                          G_CALLBACK (on_greeter_layout_selected),
941                          slave);
942        g_signal_connect (slave->priv->greeter_server,
943                          "user-selected",
944                          G_CALLBACK (on_greeter_user_selected),
945                          slave);
946        g_signal_connect (slave->priv->greeter_server,
947                          "connected",
948                          G_CALLBACK (on_greeter_connected),
949                          slave);
950        g_signal_connect (slave->priv->greeter_server,
951                          "cancelled",
952                          G_CALLBACK (on_greeter_cancel),
953                          slave);
954        g_signal_connect (slave->priv->greeter_server,
955                          "start-session-when-ready",
956                          G_CALLBACK (on_start_session_when_ready),
957                          slave);
958
959        g_signal_connect (slave->priv->greeter_server,
960                          "start-session-later",
961                          G_CALLBACK (on_start_session_later),
962                          slave);
963
964        gdm_greeter_server_start (slave->priv->greeter_server);
965
966        address = gdm_greeter_server_get_address (slave->priv->greeter_server);
967
968        g_debug ("GdmSimpleSlave: Creating greeter on %s %s %s", display_name, display_device, display_hostname);
969        slave->priv->greeter = gdm_greeter_session_new (display_name,
970                                                        display_device,
971                                                        display_hostname,
972                                                        display_is_local);
973        g_signal_connect (slave->priv->greeter,
974                          "started",
975                          G_CALLBACK (on_greeter_session_start),
976                          slave);
977        g_signal_connect (slave->priv->greeter,
978                          "stopped",
979                          G_CALLBACK (on_greeter_session_stop),
980                          slave);
981        g_signal_connect (slave->priv->greeter,
982                          "exited",
983                          G_CALLBACK (on_greeter_session_exited),
984                          slave);
985        g_signal_connect (slave->priv->greeter,
986                          "died",
987                          G_CALLBACK (on_greeter_session_died),
988                          slave);
989        g_object_set (slave->priv->greeter,
990                      "x11-authority-file", auth_file,
991                      NULL);
992        gdm_welcome_session_set_server_address (GDM_WELCOME_SESSION (slave->priv->greeter), address);
993        gdm_welcome_session_start (GDM_WELCOME_SESSION (slave->priv->greeter));
994
995        g_free (display_id);
996        g_free (display_name);
997        g_free (display_device);
998        g_free (display_hostname);
999        g_free (auth_file);
1000}
1001
1002static gboolean
1003idle_connect_to_display (GdmSimpleSlave *slave)
1004{
1005        gboolean res;
1006
1007        slave->priv->connection_attempts++;
1008
1009        res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave));
1010        if (res) {
1011                gboolean enabled;
1012                int      delay;
1013
1014                /* FIXME: handle wait-for-go */
1015
1016                setup_server (slave);
1017
1018                delay = 0;
1019                enabled = FALSE;
1020                gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay);
1021                if (! enabled || delay > 0) {
1022                        start_greeter (slave);
1023                        create_new_session (slave);
1024                } else {
1025                        reset_session (slave);
1026                }
1027        } else {
1028                if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) {
1029                        g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts);
1030                        exit (1);
1031                }
1032                return TRUE;
1033        }
1034
1035        return FALSE;
1036}
1037
1038static void
1039on_server_ready (GdmServer      *server,
1040                 GdmSimpleSlave *slave)
1041{
1042        g_idle_add ((GSourceFunc)idle_connect_to_display, slave);
1043}
1044
1045static void
1046on_server_exited (GdmServer      *server,
1047                  int             exit_code,
1048                  GdmSimpleSlave *slave)
1049{
1050        g_debug ("GdmSimpleSlave: server exited with code %d\n", exit_code);
1051
1052        gdm_slave_stopped (GDM_SLAVE (slave));
1053}
1054
1055static void
1056on_server_died (GdmServer      *server,
1057                int             signal_number,
1058                GdmSimpleSlave *slave)
1059{
1060        g_debug ("GdmSimpleSlave: server died with signal %d, (%s)",
1061                 signal_number,
1062                 g_strsignal (signal_number));
1063
1064        gdm_slave_stopped (GDM_SLAVE (slave));
1065}
1066
1067static gboolean
1068gdm_simple_slave_run (GdmSimpleSlave *slave)
1069{
1070        char    *display_name;
1071        char    *auth_file;
1072        gboolean display_is_local;
1073
1074        g_object_get (slave,
1075                      "display-is-local", &display_is_local,
1076                      "display-name", &display_name,
1077                      "display-x11-authority-file", &auth_file,
1078                      NULL);
1079
1080        /* if this is local display start a server if one doesn't
1081         * exist */
1082        if (display_is_local) {
1083                gboolean res;
1084                gboolean disable_tcp;
1085
1086                slave->priv->server = gdm_server_new (display_name, auth_file);
1087
1088                disable_tcp = TRUE;
1089                if (gdm_settings_client_get_boolean (GDM_KEY_DISALLOW_TCP,
1090                                                     &disable_tcp)) {
1091                        g_object_set (slave->priv->server,
1092                                      "disable-tcp", disable_tcp,
1093                                      NULL);
1094                }
1095
1096                g_signal_connect (slave->priv->server,
1097                                  "exited",
1098                                  G_CALLBACK (on_server_exited),
1099                                  slave);
1100                g_signal_connect (slave->priv->server,
1101                                  "died",
1102                                  G_CALLBACK (on_server_died),
1103                                  slave);
1104                g_signal_connect (slave->priv->server,
1105                                  "ready",
1106                                  G_CALLBACK (on_server_ready),
1107                                  slave);
1108
1109                res = gdm_server_start (slave->priv->server);
1110                if (! res) {
1111                        g_warning (_("Could not start the X "
1112                                     "server (your graphical environment) "
1113                                     "due to some internal error. "
1114                                     "Please contact your system administrator "
1115                                     "or check your syslog to diagnose. "
1116                                     "In the meantime this display will be "
1117                                     "disabled.  Please restart GDM when "
1118                                     "the problem is corrected."));
1119                        exit (1);
1120                }
1121
1122                g_debug ("GdmSimpleSlave: Started X server");
1123        } else {
1124                g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
1125        }
1126
1127        g_free (display_name);
1128        g_free (auth_file);
1129
1130        return TRUE;
1131}
1132
1133static gboolean
1134gdm_simple_slave_start (GdmSlave *slave)
1135{
1136        GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->start (slave);
1137
1138        gdm_simple_slave_run (GDM_SIMPLE_SLAVE (slave));
1139
1140        return TRUE;
1141}
1142
1143static gboolean
1144gdm_simple_slave_stop (GdmSlave *slave)
1145{
1146        g_debug ("GdmSimpleSlave: Stopping simple_slave");
1147
1148        GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->stop (slave);
1149
1150        if (GDM_SIMPLE_SLAVE (slave)->priv->greeter != NULL) {
1151                stop_greeter (GDM_SIMPLE_SLAVE (slave));
1152        }
1153
1154        if (GDM_SIMPLE_SLAVE (slave)->priv->session != NULL) {
1155                gdm_session_close (GDM_SESSION (GDM_SIMPLE_SLAVE (slave)->priv->session));
1156                g_object_unref (GDM_SIMPLE_SLAVE (slave)->priv->session);
1157                GDM_SIMPLE_SLAVE (slave)->priv->session = NULL;
1158        }
1159
1160        if (GDM_SIMPLE_SLAVE (slave)->priv->server != NULL) {
1161                gdm_server_stop (GDM_SIMPLE_SLAVE (slave)->priv->server);
1162                g_object_unref (GDM_SIMPLE_SLAVE (slave)->priv->server);
1163                GDM_SIMPLE_SLAVE (slave)->priv->server = NULL;
1164        }
1165
1166        return TRUE;
1167}
1168
1169static void
1170gdm_simple_slave_set_property (GObject      *object,
1171                               guint          prop_id,
1172                               const GValue *value,
1173                               GParamSpec   *pspec)
1174{
1175        switch (prop_id) {
1176        default:
1177                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1178                break;
1179        }
1180}
1181
1182static void
1183gdm_simple_slave_get_property (GObject    *object,
1184                               guint       prop_id,
1185                               GValue      *value,
1186                               GParamSpec *pspec)
1187{
1188        switch (prop_id) {
1189        default:
1190                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1191                break;
1192        }
1193}
1194
1195static GObject *
1196gdm_simple_slave_constructor (GType                  type,
1197                              guint                  n_construct_properties,
1198                              GObjectConstructParam *construct_properties)
1199{
1200        GdmSimpleSlave      *simple_slave;
1201
1202        simple_slave = GDM_SIMPLE_SLAVE (G_OBJECT_CLASS (gdm_simple_slave_parent_class)->constructor (type,
1203                                                                                 n_construct_properties,
1204                                                                                 construct_properties));
1205
1206        return G_OBJECT (simple_slave);
1207}
1208
1209static void
1210gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass)
1211{
1212        GObjectClass  *object_class = G_OBJECT_CLASS (klass);
1213        GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass);
1214
1215        object_class->get_property = gdm_simple_slave_get_property;
1216        object_class->set_property = gdm_simple_slave_set_property;
1217        object_class->constructor = gdm_simple_slave_constructor;
1218        object_class->finalize = gdm_simple_slave_finalize;
1219
1220        slave_class->start = gdm_simple_slave_start;
1221        slave_class->stop = gdm_simple_slave_stop;
1222
1223        g_type_class_add_private (klass, sizeof (GdmSimpleSlavePrivate));
1224
1225        dbus_g_object_type_install_info (GDM_TYPE_SIMPLE_SLAVE, &dbus_glib_gdm_simple_slave_object_info);
1226}
1227
1228static void
1229gdm_simple_slave_init (GdmSimpleSlave *slave)
1230{
1231        slave->priv = GDM_SIMPLE_SLAVE_GET_PRIVATE (slave);
1232}
1233
1234static void
1235gdm_simple_slave_finalize (GObject *object)
1236{
1237        GdmSimpleSlave *simple_slave;
1238
1239        g_return_if_fail (object != NULL);
1240        g_return_if_fail (GDM_IS_SIMPLE_SLAVE (object));
1241
1242        simple_slave = GDM_SIMPLE_SLAVE (object);
1243
1244        g_return_if_fail (simple_slave->priv != NULL);
1245
1246        gdm_simple_slave_stop (GDM_SLAVE (simple_slave));
1247
1248        if (simple_slave->priv->greeter_reset_id > 0) {
1249                g_source_remove (simple_slave->priv->greeter_reset_id);
1250                simple_slave->priv->greeter_reset_id = 0;
1251        }
1252
1253        G_OBJECT_CLASS (gdm_simple_slave_parent_class)->finalize (object);
1254}
1255
1256GdmSlave *
1257gdm_simple_slave_new (const char *id)
1258{
1259        GObject *object;
1260
1261        object = g_object_new (GDM_TYPE_SIMPLE_SLAVE,
1262                               "display-id", id,
1263                               NULL);
1264
1265        return GDM_SLAVE (object);
1266}
Note: See TracBrowser for help on using the repository browser.