~cyphermox/indicator-session/logind-multiple-session-lp861171

« back to all changes in this revision

Viewing changes to src/users-service-dbus.c

  • Committer: Tarmac
  • Author(s): Iain Lane
  • Date: 2013-04-23 16:55:27 UTC
  • mfrom: (387.1.6 indicator-session)
  • Revision ID: tarmac-20130423165527-ezr4d3bfh8oo7o8q
Stop using ConsoleKit and UPower for session tracking and shutdown/reboot/suspend/hibernate; migrate to logind.

Approved by Mathieu Trudel-Lapierre, PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <pwd.h> /* getpwuid() */
31
31
 
32
32
#include "dbus-accounts.h"
33
 
#include "dbus-consolekit-manager.h"
34
 
#include "dbus-consolekit-seat.h"
35
 
#include "dbus-consolekit-session.h"
 
33
#include "dbus-login1-manager.h"
 
34
#include "dbus-login1-session.h"
 
35
#include "dbus-login1-user.h"
36
36
#include "dbus-display-manager.h"
37
37
#include "dbus-user.h"
38
38
#include "shared-names.h"
39
39
#include "users-service-dbus.h"
40
40
 
41
 
#define CK_ADDR             "org.freedesktop.ConsoleKit"
42
 
#define CK_SESSION_IFACE    "org.freedesktop.ConsoleKit.Session"
 
41
#define LOGIND_ADDR             "org.freedesktop.login1"
43
42
 
44
43
/**
45
44
***
57
56
                                      const gchar       * user_object_path,
58
57
                                      UsersServiceDbus  * service);
59
58
 
60
 
static void     on_session_added     (ConsoleKitSeat    * seat,
61
 
                                      const gchar       * ssid,
62
 
                                      UsersServiceDbus  * service);
63
 
 
64
 
static void     on_session_removed   (ConsoleKitSeat    * seat,
65
 
                                      const gchar       * ssid,
66
 
                                      UsersServiceDbus  * service);
67
 
 
68
 
static void     on_session_list      (ConsoleKitSeat    * seat,
69
 
                                      GAsyncResult      * result,
70
 
                                      UsersServiceDbus  * service);
 
59
static void     on_session_added     (Login1Manager      * proxy,
 
60
                                      const gchar        * ssid,
 
61
                                      const gchar        * path,
 
62
                                      UsersServiceDbus   * service);
 
63
 
 
64
static void     on_session_removed   (Login1Manager      * proxy,
 
65
                                      const gchar        * ssid,
 
66
                                      const gchar        * path,
 
67
                                      UsersServiceDbus   * service);
 
68
 
 
69
static void     on_session_list      (Login1Manager      * proxy,
 
70
                                      GAsyncResult       * result,
 
71
                                      UsersServiceDbus   * service);
71
72
 
72
73
/***
73
74
****  Priv Struct
85
86
  GHashTable * users;
86
87
 
87
88
  GCancellable * cancellable;
88
 
  ConsoleKitSeat * seat_proxy;
89
 
  ConsoleKitManager * ck_manager_proxy;
 
89
  Login1Manager * manager_proxy;
90
90
  Accounts * accounts_proxy;
91
91
};
92
92
 
112
112
  UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv;
113
113
 
114
114
  g_clear_object (&priv->accounts_proxy);
115
 
  g_clear_object (&priv->seat_proxy);
116
 
  g_clear_object (&priv->ck_manager_proxy);
 
115
  g_clear_object (&priv->manager_proxy);
117
116
 
118
117
  if (priv->cancellable != NULL)
119
118
    {
211
210
                                    g_object_unref);
212
211
 
213
212
  /**
214
 
  ***  create the consolekit manager proxy...
 
213
  ***  create the logind manager proxy...
215
214
  **/
216
215
 
217
 
  p->ck_manager_proxy = console_kit_manager_proxy_new_for_bus_sync (
 
216
  p->manager_proxy = login1_manager_proxy_new_for_bus_sync (
218
217
                             G_BUS_TYPE_SYSTEM,
219
218
                             G_DBUS_PROXY_FLAGS_NONE,
220
 
                             "org.freedesktop.ConsoleKit",
221
 
                             "/org/freedesktop/ConsoleKit/Manager",
 
219
                             "org.freedesktop.login1",
 
220
                             "/org/freedesktop/login1",
222
221
                             NULL,
223
222
                             &error);
224
223
  if (error != NULL)
229
228
 
230
229
  p->seat = get_seat (self);
231
230
 
232
 
  /**
233
 
  ***  create the consolekit seat proxy...
234
 
  **/
235
 
 
236
 
  if (p->seat != NULL)
237
 
    {
238
 
      ConsoleKitSeat * proxy = console_kit_seat_proxy_new_for_bus_sync (
239
 
                                 G_BUS_TYPE_SYSTEM,
240
 
                                 G_DBUS_PROXY_FLAGS_NONE,
241
 
                                 "org.freedesktop.ConsoleKit",
242
 
                                 p->seat,
243
 
                                 NULL,
244
 
                                 &error);
245
 
 
246
 
      if (error != NULL)
247
 
        {
248
 
          g_warning ("Failed to connect to the ConsoleKit seat: %s", error->message);
249
 
          g_clear_error (&error);
250
 
        }
251
 
      else
252
 
        {
253
 
          g_signal_connect (proxy, "session-added",
254
 
                            G_CALLBACK (on_session_added), self);
255
 
          g_signal_connect (proxy, "session-removed",
256
 
                            G_CALLBACK (on_session_removed), self);
257
 
          console_kit_seat_call_get_sessions (proxy, p->cancellable,
258
 
                            (GAsyncReadyCallback)on_session_list, self);
259
 
          p->seat_proxy = proxy;
260
 
        }
261
 
    }
 
231
  g_signal_connect (p->manager_proxy, "session-new",
 
232
                    G_CALLBACK (on_session_added), self);
 
233
  g_signal_connect (p->manager_proxy, "session-removed",
 
234
                    G_CALLBACK (on_session_removed), self);
 
235
 
 
236
  login1_manager_call_list_sessions (p->manager_proxy, p->cancellable,
 
237
                    (GAsyncReadyCallback) on_session_list, self);
262
238
 
263
239
  /**
264
240
  ***  create the accounts manager proxy...
311
287
****
312
288
***/
313
289
 
314
 
static ConsoleKitSession*
315
 
create_consolekit_session_proxy (const char * ssid)
316
 
{
317
 
  GError * error = NULL;
318
 
 
319
 
  ConsoleKitSession * p = console_kit_session_proxy_new_for_bus_sync (
320
 
                            G_BUS_TYPE_SYSTEM,
321
 
                            G_DBUS_PROXY_FLAGS_NONE,
322
 
                            CK_ADDR,
323
 
                            ssid,
324
 
                            NULL,
325
 
                            &error);
326
 
  if (error != NULL)
327
 
    {
328
 
      g_warning ("%s: %s", G_STRLOC, error->message);
329
 
      g_error_free (error);
330
 
    }
331
 
 
332
 
  return p;
333
 
}
 
290
static Login1User*
 
291
create_login1_user_proxy (const char * path)
 
292
{
 
293
  
 
294
  GError * error = NULL;
 
295
 
 
296
  Login1User * p = login1_user_proxy_new_for_bus_sync (
 
297
                            G_BUS_TYPE_SYSTEM,
 
298
                            G_DBUS_PROXY_FLAGS_NONE,
 
299
                            LOGIND_ADDR,
 
300
                            path,
 
301
                            NULL,
 
302
                            &error);
 
303
  if (error != NULL)
 
304
    {
 
305
      g_warning ("%s: %s", G_STRLOC, error->message);
 
306
      g_error_free (error);
 
307
    }
 
308
 
 
309
  return p;
 
310
}
 
311
 
 
312
static Login1User *
 
313
create_login1_user_proxy_from_uid (UsersServiceDbus * self,
 
314
                                   guint64 uid)
 
315
{
 
316
  Login1Manager * manager = self->priv->manager_proxy;
 
317
  Login1User * user_proxy = NULL;
 
318
  gchar * user_object_path = NULL;
 
319
  GError * error = NULL;
 
320
 
 
321
  login1_manager_call_get_user_sync (manager, uid, &user_object_path, NULL,
 
322
      &error);
 
323
 
 
324
  if (error != NULL)
 
325
    {
 
326
      g_warning ("%s: %s", G_STRLOC, error->message);
 
327
      g_error_free (error);
 
328
    }
 
329
 
 
330
  if (user_object_path != NULL)
 
331
    user_proxy = create_login1_user_proxy (user_object_path);
 
332
 
 
333
  return user_proxy;
 
334
 
 
335
}
 
336
 
 
337
static Login1Session *
 
338
create_login1_session_proxy (const char * path)
 
339
{
 
340
  GError * error = NULL;
 
341
 
 
342
  Login1Session * p = login1_session_proxy_new_for_bus_sync (
 
343
                            G_BUS_TYPE_SYSTEM,
 
344
                            G_DBUS_PROXY_FLAGS_NONE,
 
345
                            LOGIND_ADDR,
 
346
                            path,
 
347
                            NULL,
 
348
                            &error);
 
349
  if (error != NULL)
 
350
    {
 
351
      g_warning ("%s: %s", G_STRLOC, error->message);
 
352
      g_error_free (error);
 
353
    }
 
354
 
 
355
  return p;
 
356
}
 
357
 
334
358
 
335
359
static gchar *
336
 
get_seat_from_session_proxy (ConsoleKitSession * session_proxy)
 
360
get_seat_from_session_proxy (Login1Session * session_proxy)
337
361
{
338
 
  gchar * seat = NULL;
 
362
  gchar * seat;
 
363
  GVariant * seatobj = login1_session_get_seat (session_proxy);
339
364
 
340
 
  GError * error = NULL;
341
 
  console_kit_session_call_get_seat_id_sync (session_proxy,
342
 
                                             &seat,
343
 
                                             NULL,
344
 
                                             &error);
345
 
  if (error != NULL)
346
 
    {
347
 
      g_debug ("%s: %s", G_STRLOC, error->message);
348
 
      g_error_free (error);
349
 
    }
 
365
  g_variant_get (seatobj, "(so)", &seat, NULL);
350
366
 
351
367
  return seat;
352
368
}
353
369
 
 
370
static const gchar *
 
371
get_display_from_session_proxy (Login1Session * session_proxy)
 
372
{
 
373
  const gchar * display;
 
374
  display = login1_session_get_display (session_proxy);
 
375
  return display;
 
376
}
 
377
 
354
378
static gchar *
355
379
get_seat (UsersServiceDbus *service)
356
380
{
357
381
  gchar * seat = NULL;
358
 
  gchar * ssid = NULL;
 
382
  gchar * path = NULL;
359
383
  GError * error = NULL;
360
384
  UsersServiceDbusPrivate * priv = service->priv;
361
 
 
362
 
  console_kit_manager_call_get_current_session_sync (priv->ck_manager_proxy,
363
 
                                                     &ssid,
364
 
                                                     NULL,
365
 
                                                     &error);
 
385
  Login1Session * session_proxy = NULL;
 
386
  pid_t pid = getpid();
 
387
 
 
388
  login1_manager_call_get_session_by_pid_sync (priv->manager_proxy,
 
389
                                               pid,
 
390
                                               &path,
 
391
                                               NULL,
 
392
                                               &error);
 
393
 
366
394
 
367
395
  if (error != NULL)
368
396
    {
369
397
      g_debug ("%s: %s", G_STRLOC, error->message);
370
398
      g_error_free (error);
 
399
      goto out;
371
400
    }
372
 
  else
 
401
 
 
402
  session_proxy = create_login1_session_proxy (path);
 
403
 
 
404
  if (!session_proxy)
373
405
    {
374
 
      ConsoleKitSession * session = create_consolekit_session_proxy (ssid);
375
 
 
376
 
      if (session != NULL)
377
 
        {
378
 
          seat = get_seat_from_session_proxy (session);
379
 
          g_object_unref (session);
380
 
        }
 
406
      g_debug ("%s: Could't get session proxy object", G_STRLOC);
381
407
    }
382
408
 
 
409
  seat = get_seat_from_session_proxy (session_proxy);
 
410
 
 
411
out:
 
412
  g_object_unref (session_proxy);
383
413
  return seat;
384
414
}
385
415
 
434
464
static void
435
465
add_user_session (UsersServiceDbus  * service,
436
466
                  AccountsUser      * user,
437
 
                  const gchar       * ssid)
 
467
                  const gchar       * ssid,
 
468
                  const gchar       * path)
438
469
{
439
 
  ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid);
 
470
  Login1Session * session_proxy = create_login1_session_proxy (path);
440
471
  if (session_proxy != NULL)
441
472
    {
442
473
      UsersServiceDbusPrivate * priv = service->priv;
446
477
      if (seat && priv->seat && !g_strcmp0 (seat, priv->seat))
447
478
        {
448
479
          /* does this session have a display? */
449
 
          gchar * display = NULL;
450
 
          console_kit_session_call_get_x11_display_sync (session_proxy,
451
 
                                                         &display,
452
 
                                                         NULL, NULL);
453
 
          const gboolean has_display = display && *display;
454
 
          g_free (display);
 
480
          const gchar * display = get_display_from_session_proxy (session_proxy);
 
481
          const gboolean has_display = g_strcmp0 ("", display) != 0;
455
482
 
456
483
          if (has_display)
457
484
            {
480
507
  const char * username = accounts_user_get_user_name (user);
481
508
  g_debug ("%s adding %s (%i)", G_STRLOC, username, (int)uid);
482
509
 
483
 
  GError * error = NULL;
484
 
  gchar ** sessions = NULL;
485
 
  console_kit_manager_call_get_sessions_for_unix_user_sync (
486
 
                                              self->priv->ck_manager_proxy,
487
 
                                              uid,
488
 
                                              &sessions,
489
 
                                              NULL,
490
 
                                              &error);
491
 
 
492
 
  if (error != NULL)
 
510
  GVariant * sessions = NULL;
 
511
 
 
512
  Login1User * user_proxy = create_login1_user_proxy_from_uid (self, uid);
 
513
 
 
514
  if (user_proxy != NULL)
493
515
    {
494
 
      g_debug ("%s: %s", G_STRLOC, error->message);
495
 
      g_error_free (error);
 
516
      sessions = login1_user_get_sessions (user_proxy);
496
517
    }
497
 
  else if (sessions != NULL)
 
518
 
 
519
  if (sessions != NULL)
498
520
    {
499
 
      int i;
 
521
      GVariantIter iter;
 
522
      g_variant_iter_init (&iter, sessions);
 
523
      gchar * id;
 
524
      gchar * object_path;
500
525
 
501
 
      for (i=0; sessions[i]; i++)
 
526
      while (g_variant_iter_loop (&iter, "(so)", &id, &object_path))
502
527
        {
503
 
          const char * const ssid = sessions[i];
504
 
          g_debug ("%s adding %s's session %s", G_STRLOC, username, ssid);
505
 
          add_user_session (self, user, ssid);
 
528
          g_debug ("%s adding %s's session %s", G_STRLOC, username, id);
 
529
          add_user_session (self, user, id, object_path);
506
530
        }
 
531
    }
507
532
 
508
 
      g_strfreev (sessions);
509
 
    }
 
533
  g_object_unref (user_proxy);
510
534
}
511
535
 
512
536
/* returns true if this property is one we use */
723
747
***/
724
748
 
725
749
static void
726
 
on_session_removed (ConsoleKitSeat   * seat_proxy,
727
 
                    const gchar      * ssid,
728
 
                    UsersServiceDbus * service)
 
750
on_session_removed (Login1Manager * proxy,
 
751
                    const gchar        * ssid,
 
752
                    const gchar        * path,
 
753
                    UsersServiceDbus   * service)
729
754
{
730
755
  g_return_if_fail (IS_USERS_SERVICE_DBUS (service));
731
756
 
757
782
}
758
783
 
759
784
static gchar*
760
 
get_unix_username_from_ssid (UsersServiceDbus * self,
761
 
                             const gchar      * ssid)
 
785
get_unix_username_from_path (UsersServiceDbus * self,
 
786
                             const gchar      * path)
762
787
{
763
 
  gchar * username = NULL;
764
788
 
765
 
  ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid);
 
789
  Login1Session * session_proxy = create_login1_session_proxy (path);
766
790
  if (session_proxy != NULL)
767
791
    {
768
 
      guint uid = 0;
769
 
      GError * error = NULL;
770
 
      console_kit_session_call_get_unix_user_sync (session_proxy,
771
 
                                                   &uid,
772
 
                                                   NULL, &error);
773
 
      if (error != NULL)
774
 
        {
775
 
          g_warning ("%s: %s", G_STRLOC, error->message);
776
 
          g_clear_error (&error);
777
 
        }
778
 
      else
779
 
        {
780
 
          errno = 0;
781
 
          const struct passwd * pwent = getpwuid (uid);
782
 
          if (pwent == NULL)
783
 
            {
784
 
              g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror(errno));
785
 
            }
786
 
          else
787
 
            {
788
 
              username = g_strdup (pwent->pw_name);
789
 
            }
790
 
        }
 
792
      gchar * username = g_strdup (login1_session_get_name (session_proxy));
 
793
 
 
794
      g_debug ("%s Getting username for %s: %s", G_STRLOC, path, username);
791
795
 
792
796
      g_object_unref (session_proxy);
 
797
 
 
798
      return username;
 
799
    } 
 
800
      else 
 
801
    {
 
802
      return NULL;
793
803
    }
794
 
 
795
 
  return username;
796
804
}
797
805
 
798
806
static gboolean
810
818
/* If the new session belongs to 'guest', update our guest_ssid.
811
819
   Otherwise, call add_user_session() to update our session tables */
812
820
static void
813
 
on_session_added (ConsoleKitSeat   * seat_proxy G_GNUC_UNUSED,
814
 
                  const gchar      * ssid,
815
 
                  UsersServiceDbus * service)
 
821
on_session_added (Login1Manager * proxy G_GNUC_UNUSED,
 
822
                  const gchar        * ssid,
 
823
                  const gchar        * path,
 
824
                  UsersServiceDbus   * service)
816
825
{
817
826
  g_return_if_fail (IS_USERS_SERVICE_DBUS(service));
818
827
 
819
 
  gchar * username = get_unix_username_from_ssid (service, ssid);
 
828
  gchar * username = get_unix_username_from_path (service, path);
820
829
  g_debug ("%s %s() username %s has new session %s", G_STRLOC, G_STRFUNC, username, ssid);
821
830
 
822
831
  if (is_guest_username (username))
834
843
 
835
844
      if (user != NULL)
836
845
        {
837
 
          add_user_session (service, user, ssid);
 
846
          add_user_session (service, user, ssid, path);
838
847
          emit_user_login_changed (service, user);
839
848
        }
840
849
    }
841
850
 
842
 
  g_free (username);
843
851
}
844
852
 
845
853
/* Receives a list of sessions and calls on_session_added() for each of them */
846
854
static void
847
 
on_session_list (ConsoleKitSeat   * seat_proxy,
 
855
on_session_list (Login1Manager    * proxy,
848
856
                 GAsyncResult     * result,
849
857
                 UsersServiceDbus * self)
850
858
{
851
859
  GError * error = NULL;
852
 
  gchar ** sessions = NULL;
 
860
  GVariant * sessions;
853
861
  g_debug ("%s bootstrapping the session list", G_STRLOC);
854
862
 
855
 
  console_kit_seat_call_get_sessions_finish (seat_proxy,
856
 
                                             &sessions,
857
 
                                             result,
858
 
                                             &error);
 
863
  login1_manager_call_list_sessions_finish (proxy,
 
864
                                            &sessions,
 
865
                                            result,
 
866
                                            &error);
859
867
 
860
868
  if (error != NULL)
861
869
    {
862
870
      g_debug ("%s: %s", G_STRLOC, error->message);
863
871
      g_error_free (error);
864
872
    }
865
 
  else if (sessions != NULL)
 
873
  else
866
874
    {
867
 
      int i;
868
 
 
869
 
      for (i=0; sessions[i]; i++)
 
875
      GVariantIter * iter;
 
876
      gchar * seat;
 
877
      gchar * path;
 
878
 
 
879
      g_variant_get (sessions, "a(susso)", &iter);
 
880
 
 
881
      while (g_variant_iter_loop (iter, 
 
882
                  "(susso)",
 
883
                  NULL,
 
884
                  NULL,
 
885
                  NULL,
 
886
                  &seat,
 
887
                  &path))
870
888
        {
871
 
          g_debug ("%s adding initial session '%s'", G_STRLOC, sessions[i]);
872
 
          on_session_added (seat_proxy, sessions[i], self);
 
889
          if (g_strcmp0 (seat, self->priv->seat) == 0)
 
890
            {
 
891
              g_debug ("%s adding initial session '%s'", G_STRLOC, path);
 
892
              on_session_added (proxy, seat, path, self);
 
893
            }
873
894
        }
874
895
 
875
 
      g_strfreev (sessions);
 
896
      g_variant_iter_free (iter);
 
897
      g_variant_unref (sessions);
 
898
 
876
899
    }
877
900
 
878
901
  g_debug ("%s done bootstrapping the session list", G_STRLOC);
1005
1028
}
1006
1029
 
1007
1030
gboolean
1008
 
users_service_dbus_can_activate_session (UsersServiceDbus * self)
1009
 
{
1010
 
  gboolean can_activate = FALSE;
1011
 
 
1012
 
  g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), can_activate);
1013
 
 
1014
 
  GError * error = NULL;
1015
 
  console_kit_seat_call_can_activate_sessions_sync (self->priv->seat_proxy,
1016
 
                                                    &can_activate,
1017
 
                                                    NULL,
1018
 
                                                    &error);
1019
 
  if (error != NULL)
1020
 
    {
1021
 
      g_warning ("%s: %s", G_STRLOC, error->message);
1022
 
      g_error_free (error);
1023
 
    }
1024
 
 
1025
 
  return can_activate;
1026
 
}
1027
 
 
1028
 
gboolean
1029
1031
users_service_dbus_is_guest_logged_in (UsersServiceDbus * self)
1030
1032
{
1031
1033
  g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE);