~ubuntu-branches/ubuntu/trusty/gdm/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/00git_logind_check.patch/daemon/gdm-slave.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha, Tim Lunn, Jeremy Bicha, Robert Ancell
  • Date: 2013-05-31 22:36:08 UTC
  • mfrom: (1.4.55)
  • Revision ID: package-import@ubuntu.com-20130531223608-33uo85niksee5460
Tags: 3.8.1.1-0ubuntu1
[ Tim Lunn ]
* New upstream release
* debian/patches/ubuntu_dont_catch_sigsegv.patch:
  - Dropped, obsolete
* debian/rules:
  - Don't rename gdm binary since that's already been
    done in the new version

[ Jeremy Bicha ]
* debian/control.in: Bump minimum glib
* debian/watch: Watch for unstable releases
* debian/patches/00git_logind_check.patch:
  - Dropped, applied in new release
* debian/patches/08_frequent-users_greeter.patch: Refreshed

[ Robert Ancell ]
* New upstream release
* debian/patches/ubuntu_daemon_autologin_tracking.patch:
* debian/patches/ubuntu_ensure_dirs.patch:
* debian/patches/ubuntu_slave-only-set-up-autologin.patch:
  - Applied upstream

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 <stdint.h>
26
 
#include <fcntl.h>
27
 
#include <unistd.h>
28
 
#include <string.h>
29
 
#include <sys/types.h>
30
 
#include <sys/wait.h>
31
 
#include <errno.h>
32
 
#include <pwd.h>
33
 
#include <grp.h>
34
 
#include <signal.h>
35
 
 
36
 
#include <glib.h>
37
 
#include <glib/gstdio.h>
38
 
#include <glib/gi18n.h>
39
 
#include <glib-object.h>
40
 
 
41
 
#include <X11/Xlib.h> /* for Display */
42
 
#include <X11/Xatom.h> /* for XA_PIXMAP */
43
 
#include <X11/cursorfont.h> /* for watch cursor */
44
 
#include <X11/extensions/Xrandr.h>
45
 
#include <X11/Xatom.h>
46
 
 
47
 
#ifdef WITH_SYSTEMD
48
 
#include <systemd/sd-login.h>
49
 
#include <systemd/sd-daemon.h>
50
 
#endif
51
 
 
52
 
#include "gdm-common.h"
53
 
#include "gdm-xerrors.h"
54
 
 
55
 
#include "gdm-slave.h"
56
 
#include "gdm-slave-glue.h"
57
 
#include "gdm-display-glue.h"
58
 
 
59
 
#include "gdm-server.h"
60
 
 
61
 
#define GDM_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SLAVE, GdmSlavePrivate))
62
 
 
63
 
#define CK_NAME      "org.freedesktop.ConsoleKit"
64
 
#define CK_PATH      "/org/freedesktop/ConsoleKit"
65
 
#define CK_INTERFACE "org.freedesktop.ConsoleKit"
66
 
 
67
 
#define CK_MANAGER_PATH      "/org/freedesktop/ConsoleKit/Manager"
68
 
#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
69
 
#define CK_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
70
 
#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
71
 
 
72
 
#define GDM_DBUS_NAME              "org.gnome.DisplayManager"
73
 
#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
74
 
 
75
 
#define GDM_SLAVE_PATH "/org/gnome/DisplayManager/Slave"
76
 
 
77
 
#define MAX_CONNECT_ATTEMPTS 10
78
 
 
79
 
struct GdmSlavePrivate
80
 
{
81
 
        GPid             pid;
82
 
        guint            output_watch_id;
83
 
        guint            error_watch_id;
84
 
 
85
 
        Display         *server_display;
86
 
 
87
 
        char            *session_id;
88
 
 
89
 
        /* cached display values */
90
 
        char            *display_id;
91
 
        char            *display_name;
92
 
        int              display_number;
93
 
        char            *display_hostname;
94
 
        gboolean         display_is_local;
95
 
        gboolean         display_is_parented;
96
 
        char            *display_seat_id;
97
 
        char            *display_x11_authority_file;
98
 
        char            *parent_display_name;
99
 
        char            *parent_display_x11_authority_file;
100
 
        char            *windowpath;
101
 
        char            *display_x11_cookie;
102
 
        gboolean         display_is_initial;
103
 
 
104
 
        GdmDBusDisplay  *display_proxy;
105
 
        GDBusConnection *connection;
106
 
        GdmDBusSlave    *skeleton;
107
 
};
108
 
 
109
 
enum {
110
 
        PROP_0,
111
 
        PROP_SESSION_ID,
112
 
        PROP_DISPLAY_ID,
113
 
        PROP_DISPLAY_NAME,
114
 
        PROP_DISPLAY_NUMBER,
115
 
        PROP_DISPLAY_HOSTNAME,
116
 
        PROP_DISPLAY_IS_LOCAL,
117
 
        PROP_DISPLAY_SEAT_ID,
118
 
        PROP_DISPLAY_X11_AUTHORITY_FILE,
119
 
        PROP_DISPLAY_IS_INITIAL,
120
 
};
121
 
 
122
 
enum {
123
 
        STOPPED,
124
 
        LAST_SIGNAL
125
 
};
126
 
 
127
 
static guint signals [LAST_SIGNAL] = { 0, };
128
 
 
129
 
static void     gdm_slave_class_init    (GdmSlaveClass *klass);
130
 
static void     gdm_slave_init          (GdmSlave      *slave);
131
 
static void     gdm_slave_finalize      (GObject       *object);
132
 
 
133
 
G_DEFINE_ABSTRACT_TYPE (GdmSlave, gdm_slave, G_TYPE_OBJECT)
134
 
 
135
 
#define CURSOR_WATCH XC_watch
136
 
 
137
 
GQuark
138
 
gdm_slave_error_quark (void)
139
 
{
140
 
        static GQuark ret = 0;
141
 
        if (ret == 0) {
142
 
                ret = g_quark_from_static_string ("gdm-slave-error-quark");
143
 
        }
144
 
 
145
 
        return ret;
146
 
}
147
 
 
148
 
static void
149
 
gdm_slave_whack_temp_auth_file (GdmSlave *slave)
150
 
{
151
 
#if 0
152
 
        uid_t old;
153
 
 
154
 
        old = geteuid ();
155
 
        if (old != 0)
156
 
                seteuid (0);
157
 
        if (d->parent_temp_auth_file != NULL) {
158
 
                VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file));
159
 
        }
160
 
        g_free (d->parent_temp_auth_file);
161
 
        d->parent_temp_auth_file = NULL;
162
 
        if (old != 0)
163
 
                seteuid (old);
164
 
#endif
165
 
}
166
 
 
167
 
 
168
 
static void
169
 
create_temp_auth_file (GdmSlave *slave)
170
 
{
171
 
#if 0
172
 
        if (d->type == TYPE_FLEXI_XNEST &&
173
 
            d->parent_auth_file != NULL) {
174
 
                if (d->parent_temp_auth_file != NULL) {
175
 
                        VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file));
176
 
                }
177
 
                g_free (d->parent_temp_auth_file);
178
 
                d->parent_temp_auth_file =
179
 
                        copy_auth_file (d->server_uid,
180
 
                                        gdm_daemon_config_get_gdmuid (),
181
 
                                        d->parent_auth_file);
182
 
        }
183
 
#endif
184
 
}
185
 
 
186
 
static void
187
 
listify_hash (const char *key,
188
 
              const char *value,
189
 
              GPtrArray  *env)
190
 
{
191
 
        char *str;
192
 
        str = g_strdup_printf ("%s=%s", key, value);
193
 
        g_debug ("GdmSlave: script environment: %s", str);
194
 
        g_ptr_array_add (env, str);
195
 
}
196
 
 
197
 
static GPtrArray *
198
 
get_script_environment (GdmSlave   *slave,
199
 
                        const char *username)
200
 
{
201
 
        GPtrArray     *env;
202
 
        GHashTable    *hash;
203
 
        struct passwd *pwent;
204
 
        char          *x_servers_file;
205
 
        char          *temp;
206
 
 
207
 
        env = g_ptr_array_new ();
208
 
 
209
 
        /* create a hash table of current environment, then update keys has necessary */
210
 
        hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
211
 
 
212
 
        /* modify environment here */
213
 
        g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/"));
214
 
        g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/"));
215
 
        g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh"));
216
 
 
217
 
        if (username != NULL) {
218
 
                g_hash_table_insert (hash, g_strdup ("LOGNAME"),
219
 
                                     g_strdup (username));
220
 
                g_hash_table_insert (hash, g_strdup ("USER"),
221
 
                                     g_strdup (username));
222
 
                g_hash_table_insert (hash, g_strdup ("USERNAME"),
223
 
                                     g_strdup (username));
224
 
 
225
 
                gdm_get_pwent_for_name (username, &pwent);
226
 
                if (pwent != NULL) {
227
 
                        if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') {
228
 
                                g_hash_table_insert (hash, g_strdup ("HOME"),
229
 
                                                     g_strdup (pwent->pw_dir));
230
 
                                g_hash_table_insert (hash, g_strdup ("PWD"),
231
 
                                                     g_strdup (pwent->pw_dir));
232
 
                        }
233
 
 
234
 
                        g_hash_table_insert (hash, g_strdup ("SHELL"),
235
 
                                             g_strdup (pwent->pw_shell));
236
 
                }
237
 
        }
238
 
 
239
 
#if 0
240
 
        if (display_is_parented) {
241
 
                g_hash_table_insert (hash, g_strdup ("GDM_PARENT_DISPLAY"), g_strdup (parent_display_name));
242
 
 
243
 
                /*g_hash_table_insert (hash, "GDM_PARENT_XAUTHORITY"), slave->priv->parent_temp_auth_file));*/
244
 
        }
245
 
#endif
246
 
 
247
 
        /* some env for use with the Pre and Post scripts */
248
 
        temp = g_strconcat (slave->priv->display_name, ".Xservers", NULL);
249
 
        x_servers_file = g_build_filename (AUTHDIR, temp, NULL);
250
 
        g_free (temp);
251
 
 
252
 
        g_hash_table_insert (hash, g_strdup ("X_SERVERS"), x_servers_file);
253
 
 
254
 
        if (! slave->priv->display_is_local) {
255
 
                g_hash_table_insert (hash, g_strdup ("REMOTE_HOST"), g_strdup (slave->priv->display_hostname));
256
 
        }
257
 
 
258
 
        /* Runs as root */
259
 
        g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (slave->priv->display_x11_authority_file));
260
 
        g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (slave->priv->display_name));
261
 
        g_hash_table_insert (hash, g_strdup ("PATH"), g_strdup (GDM_SESSION_DEFAULT_PATH));
262
 
        g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true"));
263
 
 
264
 
        g_hash_table_remove (hash, "MAIL");
265
 
 
266
 
 
267
 
        g_hash_table_foreach (hash, (GHFunc)listify_hash, env);
268
 
        g_hash_table_destroy (hash);
269
 
 
270
 
        g_ptr_array_add (env, NULL);
271
 
 
272
 
        return env;
273
 
}
274
 
 
275
 
gboolean
276
 
gdm_slave_run_script (GdmSlave   *slave,
277
 
                      const char *dir,
278
 
                      const char *login)
279
 
{
280
 
        char      *script;
281
 
        char     **argv;
282
 
        gint       status;
283
 
        GError    *error;
284
 
        GPtrArray *env;
285
 
        gboolean   res;
286
 
        gboolean   ret;
287
 
 
288
 
        ret = FALSE;
289
 
 
290
 
        g_assert (dir != NULL);
291
 
        g_assert (login != NULL);
292
 
 
293
 
        script = g_build_filename (dir, slave->priv->display_name, NULL);
294
 
        g_debug ("GdmSlave: Trying script %s", script);
295
 
        if (! (g_file_test (script, G_FILE_TEST_IS_REGULAR)
296
 
               && g_file_test (script, G_FILE_TEST_IS_EXECUTABLE))) {
297
 
                g_debug ("GdmSlave: script %s not found; skipping", script);
298
 
                g_free (script);
299
 
                script = NULL;
300
 
        }
301
 
 
302
 
        if (script == NULL
303
 
            && slave->priv->display_hostname != NULL
304
 
            && slave->priv->display_hostname[0] != '\0') {
305
 
                script = g_build_filename (dir, slave->priv->display_hostname, NULL);
306
 
                g_debug ("GdmSlave: Trying script %s", script);
307
 
                if (! (g_file_test (script, G_FILE_TEST_IS_REGULAR)
308
 
                       && g_file_test (script, G_FILE_TEST_IS_EXECUTABLE))) {
309
 
                        g_debug ("GdmSlave: script %s not found; skipping", script);
310
 
                        g_free (script);
311
 
                        script = NULL;
312
 
                }
313
 
        }
314
 
 
315
 
        if (script == NULL) {
316
 
                script = g_build_filename (dir, "Default", NULL);
317
 
                g_debug ("GdmSlave: Trying script %s", script);
318
 
                if (! (g_file_test (script, G_FILE_TEST_IS_REGULAR)
319
 
                       && g_file_test (script, G_FILE_TEST_IS_EXECUTABLE))) {
320
 
                        g_debug ("GdmSlave: script %s not found; skipping", script);
321
 
                        g_free (script);
322
 
                        script = NULL;
323
 
                }
324
 
        }
325
 
 
326
 
        if (script == NULL) {
327
 
                g_debug ("GdmSlave: no script found");
328
 
                return TRUE;
329
 
        }
330
 
 
331
 
        create_temp_auth_file (slave);
332
 
 
333
 
        g_debug ("GdmSlave: Running process: %s", script);
334
 
        error = NULL;
335
 
        if (! g_shell_parse_argv (script, NULL, &argv, &error)) {
336
 
                g_warning ("Could not parse command: %s", error->message);
337
 
                g_error_free (error);
338
 
                goto out;
339
 
        }
340
 
 
341
 
        env = get_script_environment (slave, login);
342
 
 
343
 
        res = g_spawn_sync (NULL,
344
 
                            argv,
345
 
                            (char **)env->pdata,
346
 
                            G_SPAWN_SEARCH_PATH,
347
 
                            NULL,
348
 
                            NULL,
349
 
                            NULL,
350
 
                            NULL,
351
 
                            &status,
352
 
                            &error);
353
 
 
354
 
        g_ptr_array_foreach (env, (GFunc)g_free, NULL);
355
 
        g_ptr_array_free (env, TRUE);
356
 
        g_strfreev (argv);
357
 
 
358
 
        if (! res) {
359
 
                g_warning ("GdmSlave: Unable to run script: %s", error->message);
360
 
                g_error_free (error);
361
 
        }
362
 
 
363
 
        gdm_slave_whack_temp_auth_file (slave);
364
 
 
365
 
        if (WIFEXITED (status)) {
366
 
                g_debug ("GdmSlave: Process exit status: %d", WEXITSTATUS (status));
367
 
                ret = WEXITSTATUS (status) == 0;
368
 
        }
369
 
 
370
 
 out:
371
 
        g_free (script);
372
 
 
373
 
        return ret;
374
 
}
375
 
 
376
 
static void
377
 
gdm_slave_save_root_window_of_screen (GdmSlave *slave,
378
 
                                      Atom      id_atom,
379
 
                                      int       screen_number)
380
 
{
381
 
        Window root_window;
382
 
        GC gc;
383
 
        XGCValues values;
384
 
        Pixmap pixmap;
385
 
        int width, height, depth;
386
 
 
387
 
        root_window = RootWindow (slave->priv->server_display,
388
 
                                  screen_number);
389
 
 
390
 
        width = DisplayWidth (slave->priv->server_display, screen_number);
391
 
        height = DisplayHeight (slave->priv->server_display, screen_number);
392
 
        depth = DefaultDepth (slave->priv->server_display, screen_number);
393
 
        pixmap = XCreatePixmap (slave->priv->server_display,
394
 
                                root_window,
395
 
                                width, height, depth);
396
 
 
397
 
        values.function = GXcopy;
398
 
        values.plane_mask = AllPlanes;
399
 
        values.fill_style = FillSolid;
400
 
        values.subwindow_mode = IncludeInferiors;
401
 
 
402
 
        gc = XCreateGC (slave->priv->server_display,
403
 
                        root_window,
404
 
                        GCFunction | GCPlaneMask | GCFillStyle | GCSubwindowMode,
405
 
                        &values);
406
 
 
407
 
        if (XCopyArea (slave->priv->server_display,
408
 
                       root_window, pixmap, gc, 0, 0,
409
 
                       width, height, 0, 0)) {
410
 
 
411
 
                long pixmap_as_long;
412
 
 
413
 
                pixmap_as_long = (long) pixmap;
414
 
 
415
 
                XChangeProperty (slave->priv->server_display,
416
 
                                 root_window, id_atom, XA_PIXMAP,
417
 
                                 32, PropModeReplace, (guchar *) &pixmap_as_long,
418
 
                                 1);
419
 
 
420
 
        }
421
 
 
422
 
        XFreeGC (slave->priv->server_display, gc);
423
 
}
424
 
 
425
 
void
426
 
gdm_slave_save_root_windows (GdmSlave *slave)
427
 
{
428
 
        int i, number_of_screens;
429
 
        Atom atom;
430
 
 
431
 
        number_of_screens = ScreenCount (slave->priv->server_display);
432
 
 
433
 
        atom = XInternAtom (slave->priv->server_display,
434
 
                            "_XROOTPMAP_ID", False);
435
 
 
436
 
        if (atom == 0) {
437
 
                return;
438
 
        }
439
 
 
440
 
        for (i = 0; i < number_of_screens; i++) {
441
 
                gdm_slave_save_root_window_of_screen (slave, atom, i);
442
 
        }
443
 
 
444
 
        XSync (slave->priv->server_display, False);
445
 
}
446
 
 
447
 
static void
448
 
determine_initial_cursor_position (GdmSlave *slave,
449
 
                                   int      *x,
450
 
                                   int      *y)
451
 
{
452
 
        XRRScreenResources *resources;
453
 
        RROutput primary_output;
454
 
        int i;
455
 
 
456
 
        /* If this function fails for whatever reason,
457
 
         * put the pointer in the upper left corner of the
458
 
         * first monitor
459
 
         */
460
 
        *x = 0;
461
 
        *y = 0;
462
 
 
463
 
        gdm_error_trap_push ();
464
 
        resources = XRRGetScreenResources (slave->priv->server_display,
465
 
                                           DefaultRootWindow (slave->priv->server_display));
466
 
        primary_output = XRRGetOutputPrimary (slave->priv->server_display,
467
 
                                              DefaultRootWindow (slave->priv->server_display));
468
 
        gdm_error_trap_pop ();
469
 
 
470
 
        if (resources == NULL) {
471
 
                return;
472
 
        }
473
 
 
474
 
        for (i = 0; i < resources->noutput; i++) {
475
 
                XRROutputInfo *output_info;
476
 
 
477
 
                if (primary_output == None) {
478
 
                        primary_output = resources->outputs[0];
479
 
                }
480
 
 
481
 
                if (resources->outputs[i] != primary_output) {
482
 
                        continue;
483
 
                }
484
 
 
485
 
                output_info = XRRGetOutputInfo (slave->priv->server_display,
486
 
                                                resources,
487
 
                                                resources->outputs[i]);
488
 
 
489
 
                if (output_info->connection != RR_Disconnected &&
490
 
                    output_info->crtc != 0) {
491
 
                        XRRCrtcInfo *crtc_info;
492
 
 
493
 
                        crtc_info = XRRGetCrtcInfo (slave->priv->server_display,
494
 
                                                    resources,
495
 
                                                    output_info->crtc);
496
 
                        /* position it sort of in the lower right
497
 
                         */
498
 
                        *x = crtc_info->x + .9 * crtc_info->width;
499
 
                        *y = crtc_info->y + .9 * crtc_info->height;
500
 
                        XRRFreeCrtcInfo (crtc_info);
501
 
                }
502
 
 
503
 
                XRRFreeOutputInfo (output_info);
504
 
                break;
505
 
        }
506
 
 
507
 
        XRRFreeScreenResources (resources);
508
 
}
509
 
 
510
 
void
511
 
gdm_slave_set_initial_cursor_position (GdmSlave *slave)
512
 
{
513
 
        if (slave->priv->server_display != NULL) {
514
 
                int x, y;
515
 
 
516
 
                determine_initial_cursor_position (slave, &x, &y);
517
 
                XWarpPointer(slave->priv->server_display,
518
 
                             None,
519
 
                             DefaultRootWindow (slave->priv->server_display),
520
 
                             0, 0,
521
 
                             0, 0,
522
 
                             x, y);
523
 
        }
524
 
}
525
 
 
526
 
void
527
 
gdm_slave_set_busy_cursor (GdmSlave *slave)
528
 
{
529
 
        if (slave->priv->server_display != NULL) {
530
 
                Cursor xcursor;
531
 
 
532
 
                xcursor = XCreateFontCursor (slave->priv->server_display, CURSOR_WATCH);
533
 
                XDefineCursor (slave->priv->server_display,
534
 
                               DefaultRootWindow (slave->priv->server_display),
535
 
                               xcursor);
536
 
                XFreeCursor (slave->priv->server_display, xcursor);
537
 
                XSync (slave->priv->server_display, False);
538
 
        }
539
 
}
540
 
 
541
 
static void
542
 
gdm_slave_setup_xhost_auth (XHostAddress *host_entries, XServerInterpretedAddress *si_entries)
543
 
{
544
 
        si_entries[0].type        = "localuser";
545
 
        si_entries[0].typelength  = strlen ("localuser");
546
 
        si_entries[1].type        = "localuser";
547
 
        si_entries[1].typelength  = strlen ("localuser");
548
 
        si_entries[2].type        = "localuser";
549
 
        si_entries[2].typelength  = strlen ("localuser");
550
 
 
551
 
        si_entries[0].value       = "root";
552
 
        si_entries[0].valuelength = strlen ("root");
553
 
        si_entries[1].value       = GDM_USERNAME;
554
 
        si_entries[1].valuelength = strlen (GDM_USERNAME);
555
 
        si_entries[2].value       = "gnome-initial-setup";
556
 
        si_entries[2].valuelength = strlen ("gnome-initial-setup");
557
 
 
558
 
        host_entries[0].family    = FamilyServerInterpreted;
559
 
        host_entries[0].address   = (char *) &si_entries[0];
560
 
        host_entries[0].length    = sizeof (XServerInterpretedAddress);
561
 
        host_entries[1].family    = FamilyServerInterpreted;
562
 
        host_entries[1].address   = (char *) &si_entries[1];
563
 
        host_entries[1].length    = sizeof (XServerInterpretedAddress);
564
 
        host_entries[2].family    = FamilyServerInterpreted;
565
 
        host_entries[2].address   = (char *) &si_entries[2];
566
 
        host_entries[2].length    = sizeof (XServerInterpretedAddress);
567
 
}
568
 
 
569
 
static void
570
 
gdm_slave_set_windowpath (GdmSlave *slave)
571
 
{
572
 
        /* setting WINDOWPATH for clients */
573
 
        Atom prop;
574
 
        Atom actualtype;
575
 
        int actualformat;
576
 
        unsigned long nitems;
577
 
        unsigned long bytes_after;
578
 
        unsigned char *buf;
579
 
        const char *windowpath;
580
 
        char *newwindowpath;
581
 
        unsigned long num;
582
 
        char nums[10];
583
 
        int numn;
584
 
 
585
 
        prop = XInternAtom (slave->priv->server_display, "XFree86_VT", False);
586
 
        if (prop == None) {
587
 
                g_debug ("no XFree86_VT atom\n");
588
 
                return;
589
 
        }
590
 
        if (XGetWindowProperty (slave->priv->server_display,
591
 
                DefaultRootWindow (slave->priv->server_display), prop, 0, 1,
592
 
                False, AnyPropertyType, &actualtype, &actualformat,
593
 
                &nitems, &bytes_after, &buf)) {
594
 
                g_debug ("no XFree86_VT property\n");
595
 
                return;
596
 
        }
597
 
 
598
 
        if (nitems != 1) {
599
 
                g_debug ("%lu items in XFree86_VT property!\n", nitems);
600
 
                XFree (buf);
601
 
                return;
602
 
        }
603
 
 
604
 
        switch (actualtype) {
605
 
        case XA_CARDINAL:
606
 
        case XA_INTEGER:
607
 
        case XA_WINDOW:
608
 
                switch (actualformat) {
609
 
                case  8:
610
 
                        num = (*(uint8_t  *)(void *)buf);
611
 
                        break;
612
 
                case 16:
613
 
                        num = (*(uint16_t *)(void *)buf);
614
 
                        break;
615
 
                case 32:
616
 
                        num = (*(long *)(void *)buf);
617
 
                        break;
618
 
                default:
619
 
                        g_debug ("format %d in XFree86_VT property!\n", actualformat);
620
 
                        XFree (buf);
621
 
                        return;
622
 
                }
623
 
                break;
624
 
        default:
625
 
                g_debug ("type %lx in XFree86_VT property!\n", actualtype);
626
 
                XFree (buf);
627
 
                return;
628
 
        }
629
 
        XFree (buf);
630
 
 
631
 
        windowpath = getenv ("WINDOWPATH");
632
 
        numn = snprintf (nums, sizeof (nums), "%lu", num);
633
 
        if (!windowpath) {
634
 
                newwindowpath = malloc (numn + 1);
635
 
                sprintf (newwindowpath, "%s", nums);
636
 
        } else {
637
 
                newwindowpath = malloc (strlen (windowpath) + 1 + numn + 1);
638
 
                sprintf (newwindowpath, "%s:%s", windowpath, nums);
639
 
        }
640
 
 
641
 
        slave->priv->windowpath = newwindowpath;
642
 
 
643
 
        g_setenv ("WINDOWPATH", newwindowpath, TRUE);
644
 
}
645
 
 
646
 
gboolean
647
 
gdm_slave_connect_to_x11_display (GdmSlave *slave)
648
 
{
649
 
        gboolean ret;
650
 
        sigset_t mask;
651
 
        sigset_t omask;
652
 
 
653
 
        ret = FALSE;
654
 
 
655
 
        /* We keep our own (windowless) connection (dsp) open to avoid the
656
 
         * X server resetting due to lack of active connections. */
657
 
 
658
 
        g_debug ("GdmSlave: Server is ready - opening display %s", slave->priv->display_name);
659
 
 
660
 
        g_setenv ("DISPLAY", slave->priv->display_name, TRUE);
661
 
        g_setenv ("XAUTHORITY", slave->priv->display_x11_authority_file, TRUE);
662
 
 
663
 
        sigemptyset (&mask);
664
 
        sigaddset (&mask, SIGCHLD);
665
 
        sigprocmask (SIG_BLOCK, &mask, &omask);
666
 
 
667
 
        /* Give slave access to the display independent of current hostname */
668
 
        XSetAuthorization ("MIT-MAGIC-COOKIE-1",
669
 
                           strlen ("MIT-MAGIC-COOKIE-1"),
670
 
                           slave->priv->display_x11_cookie,
671
 
                           strlen (slave->priv->display_x11_cookie));
672
 
 
673
 
        slave->priv->server_display = XOpenDisplay (slave->priv->display_name);
674
 
 
675
 
        sigprocmask (SIG_SETMASK, &omask, NULL);
676
 
 
677
 
 
678
 
        if (slave->priv->server_display == NULL) {
679
 
                g_warning ("Unable to connect to display %s", slave->priv->display_name);
680
 
                ret = FALSE;
681
 
        } else if (slave->priv->display_is_local) {
682
 
                XServerInterpretedAddress si_entries[3];
683
 
                XHostAddress              host_entries[3];
684
 
 
685
 
                g_debug ("GdmSlave: Connected to display %s", slave->priv->display_name);
686
 
                ret = TRUE;
687
 
 
688
 
                /* Give programs run by the slave and greeter access to the
689
 
                 * display independent of current hostname
690
 
                 */
691
 
                gdm_slave_setup_xhost_auth (host_entries, si_entries);
692
 
 
693
 
                gdm_error_trap_push ();
694
 
                XAddHosts (slave->priv->server_display, host_entries,
695
 
                           G_N_ELEMENTS (host_entries));
696
 
                XSync (slave->priv->server_display, False);
697
 
                if (gdm_error_trap_pop ()) {
698
 
                        g_warning ("Failed to give slave programs access to the display. Trying to proceed.");
699
 
                }
700
 
 
701
 
                gdm_slave_set_windowpath (slave);
702
 
        } else {
703
 
                g_debug ("GdmSlave: Connected to display %s", slave->priv->display_name);
704
 
                ret = TRUE;
705
 
        }
706
 
 
707
 
        return ret;
708
 
}
709
 
 
710
 
static gboolean
711
 
gdm_slave_set_slave_bus_name (GdmSlave *slave)
712
 
{
713
 
        gboolean    res;
714
 
        GError     *error;
715
 
        const char *name;
716
 
 
717
 
        name = g_dbus_connection_get_unique_name (slave->priv->connection);
718
 
 
719
 
        error = NULL;
720
 
        res = gdm_dbus_display_call_set_slave_bus_name_sync (slave->priv->display_proxy,
721
 
                                                             name,
722
 
                                                             NULL,
723
 
                                                             &error);
724
 
        if (! res) {
725
 
                g_warning ("Failed to set slave bus name on parent: %s", error->message);
726
 
                g_error_free (error);
727
 
        }
728
 
 
729
 
        return res;
730
 
}
731
 
 
732
 
static gboolean
733
 
gdm_slave_real_start (GdmSlave *slave)
734
 
{
735
 
        gboolean res;
736
 
        char    *id;
737
 
        GError  *error;
738
 
 
739
 
        g_debug ("GdmSlave: Starting slave");
740
 
 
741
 
        g_assert (slave->priv->display_proxy == NULL);
742
 
 
743
 
        g_debug ("GdmSlave: Creating proxy for %s", slave->priv->display_id);
744
 
        error = NULL;
745
 
        slave->priv->display_proxy = GDM_DBUS_DISPLAY (gdm_dbus_display_proxy_new_sync (slave->priv->connection,
746
 
                                                                                        G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
747
 
                                                                                        GDM_DBUS_NAME,
748
 
                                                                                        slave->priv->display_id,
749
 
                                                                                        NULL,
750
 
                                                                                        &error));
751
 
 
752
 
        if (slave->priv->display_proxy == NULL) {
753
 
                g_warning ("Failed to create display proxy %s: %s", slave->priv->display_id, error->message);
754
 
                g_error_free (error);
755
 
                return FALSE;
756
 
        }
757
 
 
758
 
        error = NULL;
759
 
        res = gdm_dbus_display_call_get_id_sync (slave->priv->display_proxy,
760
 
                                                 &id,
761
 
                                                 NULL,
762
 
                                                 &error);
763
 
        if (! res) {
764
 
                g_warning ("Failed to get display ID %s: %s", slave->priv->display_id, error->message);
765
 
                g_error_free (error);
766
 
                return FALSE;
767
 
        }
768
 
 
769
 
        g_debug ("GdmSlave: Got display ID: %s", id);
770
 
 
771
 
        if (strcmp (id, slave->priv->display_id) != 0) {
772
 
                g_critical ("Display ID doesn't match");
773
 
                exit (1);
774
 
        }
775
 
 
776
 
        gdm_slave_set_slave_bus_name (slave);
777
 
 
778
 
        /* cache some values up front */
779
 
        error = NULL;
780
 
        res = gdm_dbus_display_call_is_local_sync (slave->priv->display_proxy,
781
 
                                                   &slave->priv->display_is_local,
782
 
                                                   NULL,
783
 
                                                   &error);
784
 
        if (! res) {
785
 
                g_warning ("Failed to get value: %s", error->message);
786
 
                g_error_free (error);
787
 
                return FALSE;
788
 
        }
789
 
 
790
 
        error = NULL;
791
 
        res = gdm_dbus_display_call_get_x11_display_name_sync (slave->priv->display_proxy,
792
 
                                                               &slave->priv->display_name,
793
 
                                                               NULL,
794
 
                                                               &error);
795
 
        if (! res) {
796
 
                g_warning ("Failed to get value: %s", error->message);
797
 
                g_error_free (error);
798
 
                return FALSE;
799
 
        }
800
 
 
801
 
        error = NULL;
802
 
        res = gdm_dbus_display_call_get_x11_display_number_sync (slave->priv->display_proxy,
803
 
                                                                 &slave->priv->display_number,
804
 
                                                                 NULL,
805
 
                                                                 &error);
806
 
        if (! res) {
807
 
                g_warning ("Failed to get value: %s", error->message);
808
 
                g_error_free (error);
809
 
                return FALSE;
810
 
        }
811
 
 
812
 
        error = NULL;
813
 
        res = gdm_dbus_display_call_get_remote_hostname_sync (slave->priv->display_proxy,
814
 
                                                              &slave->priv->display_hostname,
815
 
                                                              NULL,
816
 
                                                              &error);
817
 
        if (! res) {
818
 
                g_warning ("Failed to get value: %s", error->message);
819
 
                g_error_free (error);
820
 
                return FALSE;
821
 
        }
822
 
 
823
 
        error = NULL;
824
 
        res = gdm_dbus_display_call_get_x11_cookie_sync (slave->priv->display_proxy,
825
 
                                                         &slave->priv->display_x11_cookie,
826
 
                                                         NULL,
827
 
                                                         &error);
828
 
        if (! res) {
829
 
                g_warning ("Failed to get value: %s", error->message);
830
 
                g_error_free (error);
831
 
                return FALSE;
832
 
        }
833
 
 
834
 
        error = NULL;
835
 
        res = gdm_dbus_display_call_get_x11_authority_file_sync (slave->priv->display_proxy,
836
 
                                                                 &slave->priv->display_x11_authority_file,
837
 
                                                                 NULL,
838
 
                                                                 &error);
839
 
        if (! res) {
840
 
                g_warning ("Failed to get value: %s", error->message);
841
 
                g_error_free (error);
842
 
                return FALSE;
843
 
        }
844
 
 
845
 
        error = NULL;
846
 
        res = gdm_dbus_display_call_get_seat_id_sync (slave->priv->display_proxy,
847
 
                                                      &slave->priv->display_seat_id,
848
 
                                                      NULL,
849
 
                                                      &error);
850
 
        if (! res) {
851
 
                g_warning ("Failed to get value: %s", error->message);
852
 
                g_error_free (error);
853
 
                return FALSE;
854
 
        }
855
 
 
856
 
        error = NULL;
857
 
        res = gdm_dbus_display_call_is_initial_sync (slave->priv->display_proxy,
858
 
                                                     &slave->priv->display_is_initial,
859
 
                                                     NULL,
860
 
                                                     &error);
861
 
        if (! res) {
862
 
                g_warning ("Failed to get value: %s", error->message);
863
 
                g_error_free (error);
864
 
                return FALSE;
865
 
        }
866
 
 
867
 
        return TRUE;
868
 
}
869
 
 
870
 
static gboolean
871
 
gdm_slave_real_stop (GdmSlave *slave)
872
 
{
873
 
        g_debug ("GdmSlave: Stopping slave");
874
 
 
875
 
        g_clear_object (&slave->priv->display_proxy);
876
 
 
877
 
        return TRUE;
878
 
}
879
 
 
880
 
gboolean
881
 
gdm_slave_start (GdmSlave *slave)
882
 
{
883
 
        gboolean ret;
884
 
 
885
 
        g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE);
886
 
 
887
 
        g_debug ("GdmSlave: starting slave");
888
 
 
889
 
        g_object_ref (slave);
890
 
        ret = GDM_SLAVE_GET_CLASS (slave)->start (slave);
891
 
        g_object_unref (slave);
892
 
 
893
 
        return ret;
894
 
}
895
 
 
896
 
gboolean
897
 
gdm_slave_stop (GdmSlave *slave)
898
 
{
899
 
        gboolean ret;
900
 
 
901
 
        g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE);
902
 
 
903
 
        g_debug ("GdmSlave: stopping slave");
904
 
 
905
 
        g_object_ref (slave);
906
 
 
907
 
        ret = GDM_SLAVE_GET_CLASS (slave)->stop (slave);
908
 
        g_signal_emit (slave, signals [STOPPED], 0);
909
 
 
910
 
        g_object_unref (slave);
911
 
        return ret;
912
 
}
913
 
 
914
 
gboolean
915
 
gdm_slave_add_user_authorization (GdmSlave   *slave,
916
 
                                  const char *username,
917
 
                                  char      **filenamep)
918
 
{
919
 
        XServerInterpretedAddress si_entries[3];
920
 
        XHostAddress              host_entries[3];
921
 
        gboolean                  res;
922
 
        GError                   *error;
923
 
        char                     *filename;
924
 
 
925
 
        filename = NULL;
926
 
 
927
 
        if (filenamep != NULL) {
928
 
                *filenamep = NULL;
929
 
        }
930
 
 
931
 
        g_debug ("GdmSlave: Requesting user authorization");
932
 
 
933
 
        error = NULL;
934
 
        res = gdm_dbus_display_call_add_user_authorization_sync (slave->priv->display_proxy,
935
 
                                                                 username,
936
 
                                                                 &filename,
937
 
                                                                 NULL,
938
 
                                                                 &error);
939
 
 
940
 
        if (! res) {
941
 
                g_warning ("Failed to add user authorization: %s", error->message);
942
 
                g_error_free (error);
943
 
        } else {
944
 
                g_debug ("GdmSlave: Got user authorization: %s", filename);
945
 
        }
946
 
 
947
 
        if (filenamep != NULL) {
948
 
                *filenamep = g_strdup (filename);
949
 
        }
950
 
        g_free (filename);
951
 
 
952
 
        /* Remove access for the programs run by slave and greeter now that the
953
 
         * user session is starting.
954
 
         */
955
 
        gdm_slave_setup_xhost_auth (host_entries, si_entries);
956
 
        gdm_error_trap_push ();
957
 
        XRemoveHosts (slave->priv->server_display, host_entries,
958
 
                      G_N_ELEMENTS (host_entries));
959
 
        XSync (slave->priv->server_display, False);
960
 
        if (gdm_error_trap_pop ()) {
961
 
                g_warning ("Failed to remove slave program access to the display. Trying to proceed.");
962
 
        }
963
 
 
964
 
 
965
 
        return res;
966
 
}
967
 
 
968
 
static char *
969
 
gdm_slave_parse_enriched_login (GdmSlave   *slave,
970
 
                                const char *username,
971
 
                                const char *display_name)
972
 
{
973
 
        char     **argv;
974
 
        int        username_len;
975
 
        GPtrArray *env;
976
 
        GError    *error;
977
 
        gboolean   res;
978
 
        char      *parsed_username;
979
 
        char      *command;
980
 
        char      *std_output;
981
 
        char      *std_error;
982
 
 
983
 
        parsed_username = NULL;
984
 
 
985
 
        if (username == NULL || username[0] == '\0') {
986
 
                return NULL;
987
 
        }
988
 
 
989
 
        /* A script may be used to generate the automatic/timed login name
990
 
           based on the display/host by ending the name with the pipe symbol
991
 
           '|'. */
992
 
 
993
 
        username_len = strlen (username);
994
 
        if (username[username_len - 1] != '|') {
995
 
                return g_strdup (username);
996
 
        }
997
 
 
998
 
        /* Remove the pipe symbol */
999
 
        command = g_strndup (username, username_len - 1);
1000
 
 
1001
 
        argv = NULL;
1002
 
        error = NULL;
1003
 
        if (! g_shell_parse_argv (command, NULL, &argv, &error)) {
1004
 
                g_warning ("GdmSlave: Could not parse command '%s': %s", command, error->message);
1005
 
                g_error_free (error);
1006
 
 
1007
 
                g_free (command);
1008
 
                goto out;
1009
 
        }
1010
 
 
1011
 
        g_debug ("GdmSlave: running '%s' to acquire auto/timed username", command);
1012
 
        g_free (command);
1013
 
 
1014
 
        env = get_script_environment (slave, NULL);
1015
 
 
1016
 
        error = NULL;
1017
 
        std_output = NULL;
1018
 
        std_error = NULL;
1019
 
        res = g_spawn_sync (NULL,
1020
 
                            argv,
1021
 
                            (char **)env->pdata,
1022
 
                            G_SPAWN_SEARCH_PATH,
1023
 
                            NULL,
1024
 
                            NULL,
1025
 
                            &std_output,
1026
 
                            &std_error,
1027
 
                            NULL,
1028
 
                            &error);
1029
 
 
1030
 
        g_ptr_array_foreach (env, (GFunc)g_free, NULL);
1031
 
        g_ptr_array_free (env, TRUE);
1032
 
        g_strfreev (argv);
1033
 
 
1034
 
        if (! res) {
1035
 
                g_warning ("GdmSlave: Unable to launch auto/timed login script '%s': %s", username, error->message);
1036
 
                g_error_free (error);
1037
 
 
1038
 
                g_free (std_output);
1039
 
                g_free (std_error);
1040
 
                goto out;
1041
 
        }
1042
 
 
1043
 
        if (std_output != NULL) {
1044
 
                g_strchomp (std_output);
1045
 
                if (std_output[0] != '\0') {
1046
 
                        parsed_username = g_strdup (std_output);
1047
 
                }
1048
 
        }
1049
 
 
1050
 
 out:
1051
 
 
1052
 
        return parsed_username;
1053
 
}
1054
 
 
1055
 
gboolean
1056
 
gdm_slave_get_timed_login_details (GdmSlave   *slave,
1057
 
                                   gboolean   *enabledp,
1058
 
                                   char      **usernamep,
1059
 
                                   int        *delayp)
1060
 
{
1061
 
        struct passwd *pwent;
1062
 
        GError        *error;
1063
 
        gboolean       res;
1064
 
        gboolean       enabled;
1065
 
        char          *username;
1066
 
        int            delay;
1067
 
 
1068
 
        username = NULL;
1069
 
        enabled = FALSE;
1070
 
        delay = 0;
1071
 
 
1072
 
        g_debug ("GdmSlave: Requesting timed login details");
1073
 
 
1074
 
        error = NULL;
1075
 
        res = gdm_dbus_display_call_get_timed_login_details_sync (slave->priv->display_proxy,
1076
 
                                                                  &enabled,
1077
 
                                                                  &username,
1078
 
                                                                  &delay,
1079
 
                                                                  NULL,
1080
 
                                                                  &error);
1081
 
        if (! res) {
1082
 
                g_warning ("Failed to get timed login details: %s", error->message);
1083
 
                g_error_free (error);
1084
 
        } else {
1085
 
                g_debug ("GdmSlave: Got timed login details: %d %s %d", enabled, username, delay);
1086
 
        }
1087
 
 
1088
 
        if (usernamep != NULL) {
1089
 
                *usernamep = gdm_slave_parse_enriched_login (slave,
1090
 
                                                             username,
1091
 
                                                             slave->priv->display_name);
1092
 
        } else {
1093
 
                g_free (username);
1094
 
 
1095
 
                if (enabledp != NULL) {
1096
 
                        *enabledp = enabled;
1097
 
                }
1098
 
                if (delayp != NULL) {
1099
 
                        *delayp = delay;
1100
 
                }
1101
 
                return TRUE;
1102
 
        }
1103
 
        g_free (username);
1104
 
 
1105
 
        if (usernamep != NULL && *usernamep != NULL) {
1106
 
                gdm_get_pwent_for_name (*usernamep, &pwent);
1107
 
                if (pwent == NULL) {
1108
 
                        g_debug ("Invalid username %s for auto/timed login",
1109
 
                                 *usernamep);
1110
 
                        g_free (*usernamep);
1111
 
                        *usernamep = NULL;
1112
 
                } else {
1113
 
                        g_debug ("Using username %s for auto/timed login",
1114
 
                                 *usernamep);
1115
 
 
1116
 
                        if (enabledp != NULL) {
1117
 
                                *enabledp = enabled;
1118
 
                        }
1119
 
                        if (delayp != NULL) {
1120
 
                                *delayp = delay;
1121
 
                        }
1122
 
               }
1123
 
        } else {
1124
 
                g_debug ("Invalid NULL username for auto/timed login");
1125
 
        }
1126
 
 
1127
 
        return res;
1128
 
}
1129
 
 
1130
 
static gboolean
1131
 
_get_uid_and_gid_for_user (const char *username,
1132
 
                           uid_t      *uid,
1133
 
                           gid_t      *gid)
1134
 
{
1135
 
        struct passwd *passwd_entry;
1136
 
 
1137
 
        g_assert (username != NULL);
1138
 
 
1139
 
        errno = 0;
1140
 
        gdm_get_pwent_for_name (username, &passwd_entry);
1141
 
 
1142
 
        if (passwd_entry == NULL) {
1143
 
                return FALSE;
1144
 
        }
1145
 
 
1146
 
        if (uid != NULL) {
1147
 
                *uid = passwd_entry->pw_uid;
1148
 
        }
1149
 
 
1150
 
        if (gid != NULL) {
1151
 
                *gid = passwd_entry->pw_gid;
1152
 
        }
1153
 
 
1154
 
        return TRUE;
1155
 
}
1156
 
 
1157
 
#ifdef WITH_CONSOLE_KIT
1158
 
 
1159
 
static gboolean
1160
 
x11_session_is_on_seat (GdmSlave        *slave,
1161
 
                        const char      *session_id,
1162
 
                        const char      *seat_id)
1163
 
{
1164
 
        GError          *error = NULL;
1165
 
        GVariant        *reply;
1166
 
        char            *sid;
1167
 
        gboolean         ret;
1168
 
        char            *x11_display_device;
1169
 
        char            *x11_display;
1170
 
 
1171
 
        ret = FALSE;
1172
 
        sid = NULL;
1173
 
        x11_display = NULL;
1174
 
        x11_display_device = NULL;
1175
 
 
1176
 
        if (seat_id == NULL || seat_id[0] == '\0' || session_id == NULL || session_id[0] == '\0') {
1177
 
                return FALSE;
1178
 
        }
1179
 
 
1180
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1181
 
                                             CK_NAME,
1182
 
                                             session_id,
1183
 
                                             CK_SESSION_INTERFACE,
1184
 
                                             "GetSeatId",
1185
 
                                             NULL, /* parameters */
1186
 
                                             G_VARIANT_TYPE ("(o)"),
1187
 
                                             G_DBUS_CALL_FLAGS_NONE,
1188
 
                                             -1,
1189
 
                                             NULL,
1190
 
                                             &error);
1191
 
        if (reply == NULL) {
1192
 
                g_debug ("Failed to identify the current seat: %s", error->message);
1193
 
                g_error_free (error);
1194
 
                return FALSE;
1195
 
        }
1196
 
 
1197
 
        g_variant_get (reply, "(o)", &sid);
1198
 
        g_variant_unref (reply);
1199
 
 
1200
 
        if (sid == NULL || sid[0] == '\0' || strcmp (sid, seat_id) != 0) {
1201
 
                g_debug ("GdmSlave: session not on current seat: %s", seat_id);
1202
 
                goto out;
1203
 
        }
1204
 
 
1205
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1206
 
                                             CK_NAME,
1207
 
                                             session_id,
1208
 
                                             CK_SESSION_INTERFACE,
1209
 
                                             "GetX11Display",
1210
 
                                             NULL, /* parameters */
1211
 
                                             G_VARIANT_TYPE ("(s)"),
1212
 
                                             G_DBUS_CALL_FLAGS_NONE,
1213
 
                                             -1,
1214
 
                                             NULL,
1215
 
                                             &error);
1216
 
        if (reply == NULL) {
1217
 
                g_error_free (error);
1218
 
                goto out;
1219
 
        }
1220
 
 
1221
 
        g_variant_get (reply, "(s)", &x11_display);
1222
 
        g_variant_unref (reply);
1223
 
 
1224
 
        /* ignore tty sessions */
1225
 
        if (x11_display == NULL || x11_display[0] == '\0') {
1226
 
                goto out;
1227
 
        }
1228
 
 
1229
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1230
 
                                             CK_NAME,
1231
 
                                             session_id,
1232
 
                                             CK_SESSION_INTERFACE,
1233
 
                                             "GetX11DisplayDevice",
1234
 
                                             NULL, /* parameters */
1235
 
                                             G_VARIANT_TYPE ("(s)"),
1236
 
                                             G_DBUS_CALL_FLAGS_NONE,
1237
 
                                             -1,
1238
 
                                             NULL,
1239
 
                                             &error);
1240
 
        if (reply == NULL) {
1241
 
                g_error_free (error);
1242
 
                goto out;
1243
 
        }
1244
 
 
1245
 
        g_variant_get (reply, "(s)", &x11_display_device);
1246
 
        g_variant_unref (reply);
1247
 
 
1248
 
        if (x11_display_device == NULL || x11_display_device[0] == '\0') {
1249
 
                goto out;
1250
 
        }
1251
 
 
1252
 
        ret = TRUE;
1253
 
 out:
1254
 
        g_free (x11_display_device);
1255
 
        g_free (x11_display);
1256
 
        g_free (sid);
1257
 
 
1258
 
        return ret;
1259
 
}
1260
 
 
1261
 
#endif
1262
 
 
1263
 
#ifdef WITH_SYSTEMD
1264
 
static char*
1265
 
gdm_slave_get_primary_session_id_for_user_from_systemd (GdmSlave   *slave,
1266
 
                                                        const char *username)
1267
 
{
1268
 
        int     res, i;
1269
 
        char  **sessions;
1270
 
        uid_t   uid;
1271
 
        char   *primary_ssid;
1272
 
        gboolean got_primary_ssid;
1273
 
 
1274
 
        primary_ssid = NULL;
1275
 
        got_primary_ssid = FALSE;
1276
 
 
1277
 
        res = sd_seat_can_multi_session (slave->priv->display_seat_id);
1278
 
        if (res < 0) {
1279
 
                g_warning ("GdmSlave: Failed to determine whether seat is multi-session capable: %s", strerror (-res));
1280
 
                return NULL;
1281
 
        } else if (res == 0) {
1282
 
                g_debug ("GdmSlave: seat is unable to activate sessions");
1283
 
                return NULL;
1284
 
        }
1285
 
 
1286
 
        if (! _get_uid_and_gid_for_user (username, &uid, NULL)) {
1287
 
                g_debug ("GdmSlave: unable to determine uid for user: %s", username);
1288
 
                return NULL;
1289
 
        }
1290
 
 
1291
 
        res = sd_seat_get_sessions (slave->priv->display_seat_id, &sessions, NULL, NULL);
1292
 
        if (res < 0) {
1293
 
                g_warning ("GdmSlave: Failed to get sessions on seat: %s", strerror (-res));
1294
 
                return NULL;
1295
 
        }
1296
 
 
1297
 
        if (sessions == NULL) {
1298
 
                g_debug ("GdmSlave: seat has no active sessions");
1299
 
                return NULL;
1300
 
        }
1301
 
 
1302
 
        for (i = 0; sessions[i] != NULL; i++) {
1303
 
                char *type;
1304
 
                char *state;
1305
 
                gboolean is_closing;
1306
 
                gboolean is_active;
1307
 
                gboolean is_x11;
1308
 
                uid_t other;
1309
 
 
1310
 
                res = sd_session_get_type (sessions[i], &type);
1311
 
 
1312
 
                if (res < 0) {
1313
 
                        g_warning ("GdmSlave: could not fetch type of session '%s': %s",
1314
 
                                   sessions[i], strerror (-res));
1315
 
                        continue;
1316
 
                }
1317
 
 
1318
 
                is_x11 = g_strcmp0 (type, "x11") == 0;
1319
 
                free (type);
1320
 
 
1321
 
                /* Only migrate to graphical sessions
1322
 
                 */
1323
 
                if (!is_x11) {
1324
 
                        continue;
1325
 
                }
1326
 
 
1327
 
                /* Always give preference to non-active sessions,
1328
 
                 * so we migrate when we can and don't when we can't
1329
 
                 */
1330
 
                res = sd_session_get_state (sessions[i], &state);
1331
 
                if (res < 0) {
1332
 
                        g_warning ("GdmSlave: could not fetch state of session '%s': %s",
1333
 
                                   sessions[i], strerror (-res));
1334
 
                        continue;
1335
 
                }
1336
 
 
1337
 
                is_closing = g_strcmp0 (state, "closing") == 0;
1338
 
                is_active = g_strcmp0 (state, "active") == 0;
1339
 
                free (state);
1340
 
 
1341
 
                /* Ignore closing sessions
1342
 
                 */
1343
 
                if (is_closing) {
1344
 
                        continue;
1345
 
                }
1346
 
 
1347
 
                res = sd_session_get_uid (sessions[i], &other);
1348
 
                if (res == 0 && other == uid && !got_primary_ssid) {
1349
 
                        g_free (primary_ssid);
1350
 
                        primary_ssid = g_strdup (sessions[i]);
1351
 
 
1352
 
                        if (!is_active) {
1353
 
                                got_primary_ssid = TRUE;
1354
 
                        }
1355
 
                }
1356
 
                free (sessions[i]);
1357
 
        }
1358
 
 
1359
 
        free (sessions);
1360
 
        return primary_ssid;
1361
 
}
1362
 
#endif
1363
 
 
1364
 
#ifdef WITH_CONSOLE_KIT
1365
 
static char *
1366
 
gdm_slave_get_primary_session_id_for_user_from_ck (GdmSlave   *slave,
1367
 
                                                   const char *username)
1368
 
{
1369
 
        gboolean      can_activate_sessions;
1370
 
        GError       *error;
1371
 
        const char  **sessions;
1372
 
        int           i;
1373
 
        char         *primary_ssid;
1374
 
        uid_t         uid;
1375
 
        GVariant     *reply;
1376
 
 
1377
 
        error = NULL;
1378
 
        primary_ssid = NULL;
1379
 
 
1380
 
        g_debug ("GdmSlave: getting proxy for seat: %s", slave->priv->display_seat_id);
1381
 
        g_debug ("GdmSlave: checking if seat can activate sessions");
1382
 
 
1383
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1384
 
                                             CK_NAME,
1385
 
                                             slave->priv->display_seat_id,
1386
 
                                             CK_SEAT_INTERFACE,
1387
 
                                             "CanActivateSessions",
1388
 
                                             NULL, /* parameters */
1389
 
                                             G_VARIANT_TYPE ("(b)"),
1390
 
                                             G_DBUS_CALL_FLAGS_NONE,
1391
 
                                             -1,
1392
 
                                             NULL,
1393
 
                                             &error);
1394
 
        if (reply == NULL) {
1395
 
                g_warning ("unable to determine if seat can activate sessions: %s", error->message);
1396
 
                g_error_free (error);
1397
 
                return NULL;
1398
 
        }
1399
 
 
1400
 
        g_variant_get (reply, "(b)", &can_activate_sessions);
1401
 
        g_variant_unref (reply);
1402
 
 
1403
 
        if (! can_activate_sessions) {
1404
 
                g_debug ("GdmSlave: seat is unable to activate sessions");
1405
 
                return NULL;
1406
 
        }
1407
 
 
1408
 
        if (! _get_uid_and_gid_for_user (username, &uid, NULL)) {
1409
 
                g_debug ("GdmSlave: unable to determine uid for user: %s", username);
1410
 
                return NULL;
1411
 
        }
1412
 
 
1413
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1414
 
                                             CK_NAME,
1415
 
                                             CK_MANAGER_PATH,
1416
 
                                             CK_MANAGER_INTERFACE,
1417
 
                                             "GetSessionsForUnixUser",
1418
 
                                             g_variant_new ("(u)", uid),
1419
 
                                             G_VARIANT_TYPE ("(ao)"),
1420
 
                                             G_DBUS_CALL_FLAGS_NONE,
1421
 
                                             -1,
1422
 
                                             NULL,
1423
 
                                             &error);
1424
 
 
1425
 
        if (reply == NULL) {
1426
 
                g_warning ("unable to determine sessions for user: %s", error->message);
1427
 
                g_error_free (error);
1428
 
                return NULL;
1429
 
        }
1430
 
 
1431
 
        g_variant_get_child (reply, 0, "^a&o", &sessions);
1432
 
        for (i = 0; sessions[i] != NULL; i++) {
1433
 
                if (x11_session_is_on_seat (slave, sessions[i], slave->priv->display_seat_id)) {
1434
 
                        primary_ssid = g_strdup (sessions[i]);
1435
 
                        break;
1436
 
                }
1437
 
        }
1438
 
 
1439
 
        g_free (sessions);
1440
 
        g_variant_unref (reply);
1441
 
        return primary_ssid;
1442
 
}
1443
 
#endif
1444
 
 
1445
 
char *
1446
 
gdm_slave_get_primary_session_id_for_user (GdmSlave   *slave,
1447
 
                                           const char *username)
1448
 
{
1449
 
 
1450
 
        if (slave->priv->display_seat_id == NULL || slave->priv->display_seat_id[0] == '\0') {
1451
 
                g_debug ("GdmSlave: display seat ID is not set; can't switch sessions");
1452
 
                return NULL;
1453
 
        }
1454
 
 
1455
 
#ifdef WITH_SYSTEMD
1456
 
        if (sd_booted () > 0) {
1457
 
                return gdm_slave_get_primary_session_id_for_user_from_systemd (slave, username);
1458
 
        }
1459
 
#endif
1460
 
 
1461
 
#ifdef WITH_CONSOLE_KIT
1462
 
        return gdm_slave_get_primary_session_id_for_user_from_ck (slave, username);
1463
 
#else
1464
 
        return NULL;
1465
 
#endif
1466
 
}
1467
 
 
1468
 
#ifdef WITH_SYSTEMD
1469
 
static gboolean
1470
 
activate_session_id_for_systemd (GdmSlave   *slave,
1471
 
                                 const char *seat_id,
1472
 
                                 const char *session_id)
1473
 
{
1474
 
        GError *error = NULL;
1475
 
        GVariant *reply;
1476
 
 
1477
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1478
 
                                             "org.freedesktop.login1",
1479
 
                                             "/org/freedesktop/login1",
1480
 
                                             "org.freedesktop.login1.Manager",
1481
 
                                             "ActivateSessionOnSeat",
1482
 
                                             g_variant_new ("(ss)", session_id, seat_id),
1483
 
                                             NULL, /* expected reply */
1484
 
                                             G_DBUS_CALL_FLAGS_NONE,
1485
 
                                             -1,
1486
 
                                             NULL,
1487
 
                                             &error);
1488
 
        if (reply == NULL) {
1489
 
                g_debug ("GdmSlave: logind 'ActivateSessionOnSeat' %s raised:\n %s\n\n",
1490
 
                         g_dbus_error_get_remote_error (error), error->message);
1491
 
                g_error_free (error);
1492
 
                return FALSE;
1493
 
        }
1494
 
 
1495
 
        g_variant_unref (reply);
1496
 
 
1497
 
        return TRUE;
1498
 
}
1499
 
#endif
1500
 
 
1501
 
#ifdef WITH_CONSOLE_KIT
1502
 
static gboolean
1503
 
activate_session_id_for_ck (GdmSlave   *slave,
1504
 
                            const char *seat_id,
1505
 
                            const char *session_id)
1506
 
{
1507
 
        GError *error = NULL;
1508
 
        GVariant *reply;
1509
 
 
1510
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1511
 
                                             CK_NAME,
1512
 
                                             seat_id,
1513
 
                                             "org.freedesktop.ConsoleKit.Seat",
1514
 
                                             "ActivateSession",
1515
 
                                             g_variant_new ("(o)", session_id),
1516
 
                                             NULL, /* expected reply */
1517
 
                                             G_DBUS_CALL_FLAGS_NONE,
1518
 
                                             -1,
1519
 
                                             NULL,
1520
 
                                             &error);
1521
 
        if (reply == NULL) {
1522
 
                g_debug ("GdmSlave: ConsoleKit %s raised:\n %s\n\n",
1523
 
                         g_dbus_error_get_remote_error (error), error->message);
1524
 
                g_error_free (error);
1525
 
                return FALSE;
1526
 
        }
1527
 
 
1528
 
        g_variant_unref (reply);
1529
 
 
1530
 
        return TRUE;
1531
 
}
1532
 
#endif
1533
 
 
1534
 
static gboolean
1535
 
activate_session_id (GdmSlave   *slave,
1536
 
                     const char *seat_id,
1537
 
                     const char *session_id)
1538
 
{
1539
 
 
1540
 
#ifdef WITH_SYSTEMD
1541
 
        if (sd_booted () > 0) {
1542
 
                return activate_session_id_for_systemd (slave, seat_id, session_id);
1543
 
        }
1544
 
#endif
1545
 
 
1546
 
#ifdef WITH_CONSOLE_KIT
1547
 
        return activate_session_id_for_ck (slave, seat_id, session_id);
1548
 
#else
1549
 
        return FALSE;
1550
 
#endif
1551
 
}
1552
 
 
1553
 
#ifdef WITH_CONSOLE_KIT
1554
 
static gboolean
1555
 
ck_session_is_active (GdmSlave   *slave,
1556
 
                      const char *seat_id,
1557
 
                      const char *session_id)
1558
 
{
1559
 
        GError *error = NULL;
1560
 
        GVariant *reply;
1561
 
        gboolean is_active;
1562
 
 
1563
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1564
 
                                             CK_NAME,
1565
 
                                             session_id,
1566
 
                                             "org.freedesktop.ConsoleKit.Session",
1567
 
                                             "IsActive",
1568
 
                                             NULL,
1569
 
                                             G_VARIANT_TYPE ("(b)"),
1570
 
                                             G_DBUS_CALL_FLAGS_NONE,
1571
 
                                             -1,
1572
 
                                             NULL,
1573
 
                                             &error);
1574
 
        if (reply == NULL) {
1575
 
                g_debug ("GdmSlave: ConsoleKit IsActive %s raised:\n %s\n\n",
1576
 
                         g_dbus_error_get_remote_error (error), error->message);
1577
 
                g_error_free (error);
1578
 
                return FALSE;
1579
 
        }
1580
 
 
1581
 
        g_variant_get (reply, "(b)", &is_active);
1582
 
        g_variant_unref (reply);
1583
 
 
1584
 
        return is_active;
1585
 
}
1586
 
#endif
1587
 
 
1588
 
static gboolean
1589
 
session_is_active (GdmSlave   *slave,
1590
 
                   const char *seat_id,
1591
 
                   const char *session_id)
1592
 
{
1593
 
#ifdef WITH_SYSTEMD
1594
 
        if (sd_booted () > 0) {
1595
 
                return sd_session_is_active (session_id) > 0;
1596
 
        }
1597
 
#endif
1598
 
 
1599
 
#ifdef WITH_CONSOLE_KIT
1600
 
        return ck_session_is_active (slave, seat_id, session_id);
1601
 
#else
1602
 
        return FALSE;
1603
 
#endif
1604
 
}
1605
 
 
1606
 
#ifdef WITH_SYSTEMD
1607
 
static gboolean
1608
 
session_unlock_for_systemd (GdmSlave   *slave,
1609
 
                            const char *ssid)
1610
 
{
1611
 
        GError *error = NULL;
1612
 
        GVariant *reply;
1613
 
 
1614
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1615
 
                                             "org.freedesktop.login1",
1616
 
                                             "/org/freedesktop/login1",
1617
 
                                             "org.freedesktop.login1.Manager",
1618
 
                                             "UnlockSession",
1619
 
                                             g_variant_new ("(s)", ssid),
1620
 
                                             NULL, /* expected reply */
1621
 
                                             G_DBUS_CALL_FLAGS_NONE,
1622
 
                                             -1,
1623
 
                                             NULL,
1624
 
                                             &error);
1625
 
        if (reply == NULL) {
1626
 
                g_debug ("GdmSlave: logind 'UnlockSession' %s raised:\n %s\n\n",
1627
 
                         g_dbus_error_get_remote_error (error), error->message);
1628
 
                g_error_free (error);
1629
 
                return FALSE;
1630
 
        }
1631
 
 
1632
 
        g_variant_unref (reply);
1633
 
 
1634
 
        return TRUE;
1635
 
}
1636
 
#endif
1637
 
 
1638
 
#ifdef WITH_CONSOLE_KIT
1639
 
static gboolean
1640
 
session_unlock_for_ck (GdmSlave   *slave,
1641
 
                       const char *ssid)
1642
 
{
1643
 
        GError *error = NULL;
1644
 
        GVariant *reply;
1645
 
 
1646
 
        reply = g_dbus_connection_call_sync (slave->priv->connection,
1647
 
                                             CK_NAME,
1648
 
                                             ssid,
1649
 
                                             CK_SESSION_INTERFACE,
1650
 
                                             "Unlock",
1651
 
                                             NULL, /* parameters */
1652
 
                                             NULL, /* expected reply */
1653
 
                                             G_DBUS_CALL_FLAGS_NONE,
1654
 
                                             -1,
1655
 
                                             NULL,
1656
 
                                             &error);
1657
 
        if (reply == NULL) {
1658
 
                g_debug ("GdmSlave: ConsoleKit %s raised:\n %s\n\n",
1659
 
                         g_dbus_error_get_remote_error (error), error->message);
1660
 
                g_error_free (error);
1661
 
                return FALSE;
1662
 
        }
1663
 
 
1664
 
        g_variant_unref (reply);
1665
 
 
1666
 
        return TRUE;
1667
 
}
1668
 
#endif
1669
 
 
1670
 
static gboolean
1671
 
session_unlock (GdmSlave   *slave,
1672
 
                const char *ssid)
1673
 
{
1674
 
 
1675
 
        g_debug ("Unlocking session %s", ssid);
1676
 
 
1677
 
#ifdef WITH_SYSTEMD
1678
 
        if (sd_booted () > 0) {
1679
 
                return session_unlock_for_systemd (slave, ssid);
1680
 
        }
1681
 
#endif
1682
 
 
1683
 
#ifdef WITH_CONSOLE_KIT
1684
 
        return session_unlock_for_ck (slave, ssid);
1685
 
#else
1686
 
        return TRUE;
1687
 
#endif
1688
 
}
1689
 
 
1690
 
gboolean
1691
 
gdm_slave_switch_to_user_session (GdmSlave   *slave,
1692
 
                                  const char *username,
1693
 
                                  gboolean    fail_if_already_switched)
1694
 
{
1695
 
        gboolean    res;
1696
 
        gboolean    ret;
1697
 
        gboolean    session_already_switched;
1698
 
        char       *ssid_to_activate;
1699
 
 
1700
 
        ret = FALSE;
1701
 
 
1702
 
        ssid_to_activate = gdm_slave_get_primary_session_id_for_user (slave, username);
1703
 
        if (ssid_to_activate == NULL) {
1704
 
                g_debug ("GdmSlave: unable to determine session to activate");
1705
 
                goto out;
1706
 
        }
1707
 
 
1708
 
        session_already_switched = session_is_active (slave, slave->priv->display_seat_id, ssid_to_activate);
1709
 
 
1710
 
        g_debug ("GdmSlave: Activating session: '%s'", ssid_to_activate);
1711
 
 
1712
 
        if (session_already_switched && fail_if_already_switched) {
1713
 
                g_debug ("GdmSlave: unable to activate session since it's already active: %s", ssid_to_activate);
1714
 
                goto out;
1715
 
        }
1716
 
 
1717
 
        if (!session_already_switched) {
1718
 
                res = activate_session_id (slave, slave->priv->display_seat_id, ssid_to_activate);
1719
 
                if (! res) {
1720
 
                        g_debug ("GdmSlave: unable to activate session: %s", ssid_to_activate);
1721
 
                        goto out;
1722
 
                }
1723
 
        }
1724
 
 
1725
 
        res = session_unlock (slave, ssid_to_activate);
1726
 
        if (!res) {
1727
 
                /* this isn't fatal */
1728
 
                g_debug ("GdmSlave: unable to unlock session: %s", ssid_to_activate);
1729
 
        }
1730
 
 
1731
 
        ret = TRUE;
1732
 
 
1733
 
 out:
1734
 
        g_free (ssid_to_activate);
1735
 
 
1736
 
        return ret;
1737
 
}
1738
 
 
1739
 
static void
1740
 
_gdm_slave_set_session_id (GdmSlave   *slave,
1741
 
                           const char *id)
1742
 
{
1743
 
        g_free (slave->priv->session_id);
1744
 
        slave->priv->session_id = g_strdup (id);
1745
 
}
1746
 
 
1747
 
static void
1748
 
_gdm_slave_set_display_id (GdmSlave   *slave,
1749
 
                           const char *id)
1750
 
{
1751
 
        g_free (slave->priv->display_id);
1752
 
        slave->priv->display_id = g_strdup (id);
1753
 
}
1754
 
 
1755
 
static void
1756
 
_gdm_slave_set_display_name (GdmSlave   *slave,
1757
 
                             const char *name)
1758
 
{
1759
 
        g_free (slave->priv->display_name);
1760
 
        slave->priv->display_name = g_strdup (name);
1761
 
}
1762
 
 
1763
 
static void
1764
 
_gdm_slave_set_display_number (GdmSlave   *slave,
1765
 
                               int         number)
1766
 
{
1767
 
        slave->priv->display_number = number;
1768
 
}
1769
 
 
1770
 
static void
1771
 
_gdm_slave_set_display_hostname (GdmSlave   *slave,
1772
 
                                 const char *name)
1773
 
{
1774
 
        g_free (slave->priv->display_hostname);
1775
 
        slave->priv->display_hostname = g_strdup (name);
1776
 
}
1777
 
 
1778
 
static void
1779
 
_gdm_slave_set_display_x11_authority_file (GdmSlave   *slave,
1780
 
                                           const char *name)
1781
 
{
1782
 
        g_free (slave->priv->display_x11_authority_file);
1783
 
        slave->priv->display_x11_authority_file = g_strdup (name);
1784
 
}
1785
 
 
1786
 
static void
1787
 
_gdm_slave_set_display_seat_id (GdmSlave   *slave,
1788
 
                                const char *id)
1789
 
{
1790
 
        g_free (slave->priv->display_seat_id);
1791
 
        slave->priv->display_seat_id = g_strdup (id);
1792
 
}
1793
 
 
1794
 
static void
1795
 
_gdm_slave_set_display_is_local (GdmSlave   *slave,
1796
 
                                 gboolean    is)
1797
 
{
1798
 
        slave->priv->display_is_local = is;
1799
 
}
1800
 
 
1801
 
static void
1802
 
_gdm_slave_set_display_is_initial (GdmSlave   *slave,
1803
 
                                   gboolean    is)
1804
 
{
1805
 
        slave->priv->display_is_initial = is;
1806
 
}
1807
 
 
1808
 
static void
1809
 
gdm_slave_set_property (GObject      *object,
1810
 
                        guint         prop_id,
1811
 
                        const GValue *value,
1812
 
                        GParamSpec   *pspec)
1813
 
{
1814
 
        GdmSlave *self;
1815
 
 
1816
 
        self = GDM_SLAVE (object);
1817
 
 
1818
 
        switch (prop_id) {
1819
 
        case PROP_SESSION_ID:
1820
 
                _gdm_slave_set_session_id (self, g_value_get_string (value));
1821
 
                break;
1822
 
        case PROP_DISPLAY_ID:
1823
 
                _gdm_slave_set_display_id (self, g_value_get_string (value));
1824
 
                break;
1825
 
        case PROP_DISPLAY_NAME:
1826
 
                _gdm_slave_set_display_name (self, g_value_get_string (value));
1827
 
                break;
1828
 
        case PROP_DISPLAY_NUMBER:
1829
 
                _gdm_slave_set_display_number (self, g_value_get_int (value));
1830
 
                break;
1831
 
        case PROP_DISPLAY_HOSTNAME:
1832
 
                _gdm_slave_set_display_hostname (self, g_value_get_string (value));
1833
 
                break;
1834
 
        case PROP_DISPLAY_SEAT_ID:
1835
 
                _gdm_slave_set_display_seat_id (self, g_value_get_string (value));
1836
 
                break;
1837
 
        case PROP_DISPLAY_X11_AUTHORITY_FILE:
1838
 
                _gdm_slave_set_display_x11_authority_file (self, g_value_get_string (value));
1839
 
                break;
1840
 
        case PROP_DISPLAY_IS_LOCAL:
1841
 
                _gdm_slave_set_display_is_local (self, g_value_get_boolean (value));
1842
 
                break;
1843
 
        case PROP_DISPLAY_IS_INITIAL:
1844
 
                _gdm_slave_set_display_is_initial (self, g_value_get_boolean (value));
1845
 
                break;
1846
 
        default:
1847
 
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1848
 
                break;
1849
 
        }
1850
 
}
1851
 
 
1852
 
static void
1853
 
gdm_slave_get_property (GObject    *object,
1854
 
                        guint       prop_id,
1855
 
                        GValue     *value,
1856
 
                        GParamSpec *pspec)
1857
 
{
1858
 
        GdmSlave *self;
1859
 
 
1860
 
        self = GDM_SLAVE (object);
1861
 
 
1862
 
        switch (prop_id) {
1863
 
        case PROP_SESSION_ID:
1864
 
                g_value_set_string (value, self->priv->session_id);
1865
 
                break;
1866
 
        case PROP_DISPLAY_ID:
1867
 
                g_value_set_string (value, self->priv->display_id);
1868
 
                break;
1869
 
        case PROP_DISPLAY_NAME:
1870
 
                g_value_set_string (value, self->priv->display_name);
1871
 
                break;
1872
 
        case PROP_DISPLAY_NUMBER:
1873
 
                g_value_set_int (value, self->priv->display_number);
1874
 
                break;
1875
 
        case PROP_DISPLAY_HOSTNAME:
1876
 
                g_value_set_string (value, self->priv->display_hostname);
1877
 
                break;
1878
 
        case PROP_DISPLAY_SEAT_ID:
1879
 
                g_value_set_string (value, self->priv->display_seat_id);
1880
 
                break;
1881
 
        case PROP_DISPLAY_X11_AUTHORITY_FILE:
1882
 
                g_value_set_string (value, self->priv->display_x11_authority_file);
1883
 
                break;
1884
 
        case PROP_DISPLAY_IS_LOCAL:
1885
 
                g_value_set_boolean (value, self->priv->display_is_local);
1886
 
                break;
1887
 
        case PROP_DISPLAY_IS_INITIAL:
1888
 
                g_value_set_boolean (value, self->priv->display_is_initial);
1889
 
                break;
1890
 
        default:
1891
 
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1892
 
                break;
1893
 
        }
1894
 
}
1895
 
 
1896
 
static gboolean
1897
 
handle_open_session (GdmDBusSlave          *skeleton,
1898
 
                     GDBusMethodInvocation *invocation,
1899
 
                     int                    pid_of_caller,
1900
 
                     int                    uid_of_caller,
1901
 
                     GdmSlave              *slave)
1902
 
{
1903
 
        GError        *error;
1904
 
        GdmSlaveClass *slave_class;
1905
 
        char          *address;
1906
 
 
1907
 
        slave_class = GDM_SLAVE_GET_CLASS (slave);
1908
 
        if (slave_class->open_session == NULL) {
1909
 
                g_dbus_method_invocation_return_dbus_error (invocation,
1910
 
                                                            "org.gnome.DisplayManager.Slave.Unsupported",
1911
 
                                                            "Connections to the slave are not supported by this slave");
1912
 
                return TRUE;
1913
 
        }
1914
 
 
1915
 
        error = NULL;
1916
 
        address = NULL;
1917
 
        if (!slave_class->open_session (slave,
1918
 
                                        (GPid) pid_of_caller,
1919
 
                                        (uid_t) uid_of_caller,
1920
 
                                        &address,
1921
 
                                        &error)) {
1922
 
                g_dbus_method_invocation_return_gerror (invocation, error);
1923
 
                g_error_free (error);
1924
 
                return TRUE;
1925
 
        }
1926
 
 
1927
 
        gdm_dbus_slave_complete_open_session (skeleton, invocation, address);
1928
 
 
1929
 
        g_free (address);
1930
 
        return TRUE;
1931
 
}
1932
 
 
1933
 
static void
1934
 
on_reauthentication_channel_opened (GdmSlave              *slave,
1935
 
                                    GAsyncResult          *result,
1936
 
                                    GDBusMethodInvocation *invocation)
1937
 
{
1938
 
        GdmSlaveClass      *slave_class;
1939
 
        GError             *error;
1940
 
        char               *address;
1941
 
 
1942
 
        slave_class = GDM_SLAVE_GET_CLASS (slave);
1943
 
 
1944
 
        g_assert (slave_class->open_reauthentication_channel_finish != NULL);
1945
 
 
1946
 
        error = NULL;
1947
 
        address = slave_class->open_reauthentication_channel_finish (slave, result, &error);
1948
 
 
1949
 
        if (address == NULL) {
1950
 
                g_dbus_method_invocation_return_gerror (invocation, error);
1951
 
        } else {
1952
 
                gdm_dbus_slave_complete_open_reauthentication_channel (slave->priv->skeleton,
1953
 
                                                                       invocation,
1954
 
                                                                       address);
1955
 
        }
1956
 
 
1957
 
        g_object_unref (invocation);
1958
 
}
1959
 
 
1960
 
static gboolean
1961
 
handle_open_reauthentication_channel (GdmDBusSlave          *skeleton,
1962
 
                                      GDBusMethodInvocation *invocation,
1963
 
                                      const char            *username,
1964
 
                                      GPid                   pid_of_caller,
1965
 
                                      uid_t                  uid_of_caller,
1966
 
                                      GdmSlave              *slave)
1967
 
{
1968
 
        GdmSlaveClass *slave_class;
1969
 
 
1970
 
        slave_class = GDM_SLAVE_GET_CLASS (slave);
1971
 
        if (slave_class->open_reauthentication_channel == NULL) {
1972
 
                g_dbus_method_invocation_return_dbus_error (invocation,
1973
 
                                                            "org.gnome.DisplayManager.Slave.Unsupported",
1974
 
                                                            "Connections to the slave are not supported by this slave");
1975
 
                return TRUE;
1976
 
        }
1977
 
 
1978
 
        slave_class->open_reauthentication_channel (slave,
1979
 
                                                    username,
1980
 
                                                    pid_of_caller,
1981
 
                                                    uid_of_caller,
1982
 
                                                    (GAsyncReadyCallback)
1983
 
                                                    on_reauthentication_channel_opened,
1984
 
                                                    g_object_ref (invocation),
1985
 
                                                    NULL);
1986
 
 
1987
 
        return TRUE;
1988
 
}
1989
 
 
1990
 
static gboolean
1991
 
register_slave (GdmSlave *slave)
1992
 
{
1993
 
        GError *error;
1994
 
 
1995
 
        error = NULL;
1996
 
        slave->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM,
1997
 
                                                  NULL,
1998
 
                                                  &error);
1999
 
        if (slave->priv->connection == NULL) {
2000
 
                g_critical ("error getting system bus: %s", error->message);
2001
 
                g_error_free (error);
2002
 
                exit (1);
2003
 
        }
2004
 
 
2005
 
        slave->priv->skeleton = GDM_DBUS_SLAVE (gdm_dbus_slave_skeleton_new ());
2006
 
 
2007
 
        g_signal_connect (slave->priv->skeleton,
2008
 
                          "handle-open-session",
2009
 
                          G_CALLBACK (handle_open_session),
2010
 
                          slave);
2011
 
        g_signal_connect (slave->priv->skeleton,
2012
 
                          "handle-open-reauthentication-channel",
2013
 
                          G_CALLBACK (handle_open_reauthentication_channel),
2014
 
                          slave);
2015
 
 
2016
 
        g_object_bind_property (G_OBJECT (slave),
2017
 
                                "session-id",
2018
 
                                G_OBJECT (slave->priv->skeleton),
2019
 
                                "session-id",
2020
 
                                G_BINDING_DEFAULT);
2021
 
 
2022
 
        gdm_slave_export_interface (slave,
2023
 
                                    G_DBUS_INTERFACE_SKELETON (slave->priv->skeleton));
2024
 
 
2025
 
        return TRUE;
2026
 
}
2027
 
 
2028
 
static GObject *
2029
 
gdm_slave_constructor (GType                  type,
2030
 
                       guint                  n_construct_properties,
2031
 
                       GObjectConstructParam *construct_properties)
2032
 
{
2033
 
        GdmSlave      *slave;
2034
 
        gboolean       res;
2035
 
 
2036
 
        slave = GDM_SLAVE (G_OBJECT_CLASS (gdm_slave_parent_class)->constructor (type,
2037
 
                                                                                 n_construct_properties,
2038
 
                                                                                 construct_properties));
2039
 
        g_debug ("GdmSlave: Registering");
2040
 
 
2041
 
        res = register_slave (slave);
2042
 
        if (! res) {
2043
 
                g_warning ("Unable to register slave with system bus");
2044
 
        }
2045
 
 
2046
 
        return G_OBJECT (slave);
2047
 
}
2048
 
 
2049
 
static void
2050
 
gdm_slave_class_init (GdmSlaveClass *klass)
2051
 
{
2052
 
        GObjectClass    *object_class = G_OBJECT_CLASS (klass);
2053
 
 
2054
 
        object_class->get_property = gdm_slave_get_property;
2055
 
        object_class->set_property = gdm_slave_set_property;
2056
 
        object_class->constructor = gdm_slave_constructor;
2057
 
        object_class->finalize = gdm_slave_finalize;
2058
 
 
2059
 
        klass->start = gdm_slave_real_start;
2060
 
        klass->stop = gdm_slave_real_stop;
2061
 
 
2062
 
        g_type_class_add_private (klass, sizeof (GdmSlavePrivate));
2063
 
 
2064
 
        g_object_class_install_property (object_class,
2065
 
                                         PROP_SESSION_ID,
2066
 
                                         g_param_spec_string ("session-id",
2067
 
                                                              "Session id",
2068
 
                                                              "ID of session",
2069
 
                                                              NULL,
2070
 
                                                              G_PARAM_READWRITE));
2071
 
        g_object_class_install_property (object_class,
2072
 
                                         PROP_DISPLAY_ID,
2073
 
                                         g_param_spec_string ("display-id",
2074
 
                                                              "id",
2075
 
                                                              "id",
2076
 
                                                              NULL,
2077
 
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2078
 
        g_object_class_install_property (object_class,
2079
 
                                         PROP_DISPLAY_NAME,
2080
 
                                         g_param_spec_string ("display-name",
2081
 
                                                              "display name",
2082
 
                                                              "display name",
2083
 
                                                              NULL,
2084
 
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2085
 
        g_object_class_install_property (object_class,
2086
 
                                         PROP_DISPLAY_NUMBER,
2087
 
                                         g_param_spec_int ("display-number",
2088
 
                                                           "display number",
2089
 
                                                           "display number",
2090
 
                                                           -1,
2091
 
                                                           G_MAXINT,
2092
 
                                                           -1,
2093
 
                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2094
 
        g_object_class_install_property (object_class,
2095
 
                                         PROP_DISPLAY_HOSTNAME,
2096
 
                                         g_param_spec_string ("display-hostname",
2097
 
                                                              "display hostname",
2098
 
                                                              "display hostname",
2099
 
                                                              NULL,
2100
 
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2101
 
        g_object_class_install_property (object_class,
2102
 
                                         PROP_DISPLAY_SEAT_ID,
2103
 
                                         g_param_spec_string ("display-seat-id",
2104
 
                                                              "",
2105
 
                                                              "",
2106
 
                                                              NULL,
2107
 
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2108
 
        g_object_class_install_property (object_class,
2109
 
                                         PROP_DISPLAY_X11_AUTHORITY_FILE,
2110
 
                                         g_param_spec_string ("display-x11-authority-file",
2111
 
                                                              "",
2112
 
                                                              "",
2113
 
                                                              NULL,
2114
 
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2115
 
        g_object_class_install_property (object_class,
2116
 
                                         PROP_DISPLAY_IS_LOCAL,
2117
 
                                         g_param_spec_boolean ("display-is-local",
2118
 
                                                               "display is local",
2119
 
                                                               "display is local",
2120
 
                                                               TRUE,
2121
 
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2122
 
        g_object_class_install_property (object_class,
2123
 
                                         PROP_DISPLAY_IS_INITIAL,
2124
 
                                         g_param_spec_boolean ("display-is-initial",
2125
 
                                                               NULL,
2126
 
                                                               NULL,
2127
 
                                                               FALSE,
2128
 
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2129
 
 
2130
 
        signals [STOPPED] =
2131
 
                g_signal_new ("stopped",
2132
 
                              G_TYPE_FROM_CLASS (object_class),
2133
 
                              G_SIGNAL_RUN_LAST,
2134
 
                              G_STRUCT_OFFSET (GdmSlaveClass, stopped),
2135
 
                              NULL,
2136
 
                              NULL,
2137
 
                              g_cclosure_marshal_VOID__VOID,
2138
 
                              G_TYPE_NONE,
2139
 
                              0);
2140
 
}
2141
 
 
2142
 
static void
2143
 
gdm_slave_init (GdmSlave *slave)
2144
 
{
2145
 
 
2146
 
        slave->priv = GDM_SLAVE_GET_PRIVATE (slave);
2147
 
 
2148
 
        slave->priv->pid = -1;
2149
 
}
2150
 
 
2151
 
static void
2152
 
gdm_slave_finalize (GObject *object)
2153
 
{
2154
 
        GdmSlave *slave;
2155
 
 
2156
 
        g_return_if_fail (object != NULL);
2157
 
        g_return_if_fail (GDM_IS_SLAVE (object));
2158
 
 
2159
 
        slave = GDM_SLAVE (object);
2160
 
 
2161
 
        g_return_if_fail (slave->priv != NULL);
2162
 
 
2163
 
        gdm_slave_real_stop (slave);
2164
 
 
2165
 
        g_free (slave->priv->display_id);
2166
 
        g_free (slave->priv->display_name);
2167
 
        g_free (slave->priv->display_hostname);
2168
 
        g_free (slave->priv->display_seat_id);
2169
 
        g_free (slave->priv->display_x11_authority_file);
2170
 
        g_free (slave->priv->parent_display_name);
2171
 
        g_free (slave->priv->parent_display_x11_authority_file);
2172
 
        g_free (slave->priv->windowpath);
2173
 
        g_free (slave->priv->display_x11_cookie);
2174
 
 
2175
 
        G_OBJECT_CLASS (gdm_slave_parent_class)->finalize (object);
2176
 
}
2177
 
 
2178
 
void
2179
 
gdm_slave_export_interface (GdmSlave               *slave,
2180
 
                            GDBusInterfaceSkeleton *interface)
2181
 
{
2182
 
        g_dbus_interface_skeleton_export (interface,
2183
 
                                          slave->priv->connection,
2184
 
                                          GDM_SLAVE_PATH,
2185
 
                                          NULL);
2186
 
}