1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21 #include "config.h"
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <signal.h>
29 #include <errno.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32
33 #ifdef HAVE_PATHS_H
34 #include <paths.h>
35 #endif /* HAVE_PATHS_H */
36
37 #include <glib.h>
38 #include <glib/gi18n-lib.h>
39 #include <glib/gstdio.h>
40 #include <glib-object.h>
41 #include <gio/gio.h>
42 #include <gio/gunixinputstream.h>
43
44 #ifdef WITH_SYSTEMD
45 #include <systemd/sd-login.h>
46
47 /* check if logind is running */
48 #define LOGIND_RUNNING() (access("/run/systemd/seats/", F_OK) >= 0)
49 #endif
50
51 #include "act-user-manager.h"
52 #include "act-user-private.h"
53 #include "accounts-generated.h"
54 #include "ck-manager-generated.h"
55 #include "ck-seat-generated.h"
56 #include "ck-session-generated.h"
57
58 /**
59 * SECTION:act-user-manager
60 * @title: ActUserManager
61 * @short_description: manages ActUser objects
62 *
63 * ActUserManager is a manager object that gives access to user
64 * creation, deletion, enumeration, etc.
65 *
66 * There is typically a singleton ActUserManager object, which
67 * can be obtained by act_user_manager_get_default().
68 */
69
70 /**
71 * ActUserManager:
72 *
73 * A user manager object.
74 */
75
76 /**
77 * ACT_USER_MANAGER_ERROR:
78 *
79 * The GError domain for #ActUserManagerError errors
80 */
81
82 /**
83 * ActUserManagerError:
84 * @ACT_USER_MANAGER_ERROR_FAILED: Generic failure
85 * @ACT_USER_MANAGER_ERROR_USER_EXISTS: The user already exists
86 * @ACT_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST: The user does not exist
87 * @ACT_USER_MANAGER_ERROR_PERMISSION_DENIED: Permission denied
88 * @ACT_USER_MANAGER_ERROR_NOT_SUPPORTED: Operation not supported
89 *
90 * Various error codes returned by the accounts service.
91 */
92
93 #define CK_NAME "org.freedesktop.ConsoleKit"
94
95 #define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
96 #define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
97 #define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
98 #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
99
100 #define ACCOUNTS_NAME "org.freedesktop.Accounts"
101 #define ACCOUNTS_PATH "/org/freedesktop/Accounts"
102 #define ACCOUNTS_INTERFACE "org.freedesktop.Accounts"
103
104 typedef enum {
105 ACT_USER_MANAGER_SEAT_STATE_UNLOADED = 0,
106 ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_ID,
107 ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_PROXY,
108 ACT_USER_MANAGER_SEAT_STATE_GET_ID,
109 ACT_USER_MANAGER_SEAT_STATE_GET_SEAT_PROXY,
110 ACT_USER_MANAGER_SEAT_STATE_LOADED,
111 } ActUserManagerSeatState;
112
113 typedef struct
114 {
115 ActUserManagerSeatState state;
116 char *id;
117 char *session_id;
118 ConsoleKitSeat *seat_proxy;
119 ConsoleKitSession *session_proxy;
120 guint load_idle_id;
121 #ifdef WITH_SYSTEMD
122 sd_login_monitor *session_monitor;
123 GInputStream *session_monitor_stream;
124 guint session_monitor_source_id;
125 #endif
126 } ActUserManagerSeat;
127
128 typedef enum {
129 ACT_USER_MANAGER_NEW_SESSION_STATE_UNLOADED = 0,
130 ACT_USER_MANAGER_NEW_SESSION_STATE_GET_PROXY,
131 ACT_USER_MANAGER_NEW_SESSION_STATE_GET_UID,
132 ACT_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY,
133 ACT_USER_MANAGER_NEW_SESSION_STATE_MAYBE_ADD,
134 ACT_USER_MANAGER_NEW_SESSION_STATE_LOADED,
135 } ActUserManagerNewSessionState;
136
137 typedef struct
138 {
139 ActUserManager *manager;
140 ActUserManagerNewSessionState state;
141 char *id;
142 ConsoleKitSession *proxy;
143 GCancellable *cancellable;
144 uid_t uid;
145 char *x11_display;
146 gsize pending_calls;
147 } ActUserManagerNewSession;
148
149 typedef enum {
150 ACT_USER_MANAGER_GET_USER_STATE_UNFETCHED = 0,
151 ACT_USER_MANAGER_GET_USER_STATE_WAIT_FOR_LOADED,
152 ACT_USER_MANAGER_GET_USER_STATE_ASK_ACCOUNTS_SERVICE,
153 ACT_USER_MANAGER_GET_USER_STATE_FETCHED
154 } ActUserManagerGetUserState;
155
156 typedef enum {
157 ACT_USER_MANAGER_FETCH_USER_FROM_USERNAME_REQUEST,
158 ACT_USER_MANAGER_FETCH_USER_FROM_ID_REQUEST,
159 } ActUserManagerFetchUserRequestType;
160
161 typedef struct
162 {
163 ActUserManager *manager;
164 ActUserManagerGetUserState state;
165 ActUser *user;
166 ActUserManagerFetchUserRequestType type;
167 union {
168 char *username;
169 uid_t uid;
170 };
171 char *object_path;
172 char *description;
173 } ActUserManagerFetchUserRequest;
174
175 typedef struct
176 {
177 GHashTable *normal_users_by_name;
178 GHashTable *system_users_by_name;
179 GHashTable *users_by_object_path;
180 GHashTable *sessions;
181 GDBusConnection *connection;
182 AccountsAccounts *accounts_proxy;
183 ConsoleKitManager *ck_manager_proxy;
184
185 ActUserManagerSeat seat;
186
187 GSList *new_sessions;
188 GSList *new_users;
189 GSList *new_users_inhibiting_load;
190 GSList *fetch_user_requests;
191
192 GSList *exclude_usernames;
193 GSList *include_usernames;
194
195 guint load_id;
196
197 gboolean is_loaded;
198 gboolean has_multiple_users;
199 gboolean getting_sessions;
200 gboolean list_cached_users_done;
201 } ActUserManagerPrivate;
202
203 enum {
204 PROP_0,
205 PROP_INCLUDE_USERNAMES_LIST,
206 PROP_EXCLUDE_USERNAMES_LIST,
207 PROP_IS_LOADED,
208 PROP_HAS_MULTIPLE_USERS
209 };
210
211 enum {
212 USER_ADDED,
213 USER_REMOVED,
214 USER_IS_LOGGED_IN_CHANGED,
215 USER_CHANGED,
216 LAST_SIGNAL
217 };
218
219 static guint signals [LAST_SIGNAL] = { 0, };
220
221 static void act_user_manager_class_init (ActUserManagerClass *klass);
222 static void act_user_manager_init (ActUserManager *user_manager);
223 static void act_user_manager_finalize (GObject *object);
224
225 static gboolean ensure_accounts_proxy (ActUserManager *manager);
226 static gboolean load_seat_incrementally (ActUserManager *manager);
227 static void unload_seat (ActUserManager *manager);
228 static void load_users (ActUserManager *manager);
229 static void load_user (ActUserManager *manager,
230 const char *username);
231 static void act_user_manager_queue_load (ActUserManager *manager);
232 static void queue_load_seat (ActUserManager *manager);
233
234 static void load_new_session_incrementally (ActUserManagerNewSession *new_session);
235 static void set_is_loaded (ActUserManager *manager, gboolean is_loaded);
236
237 static void on_new_user_loaded (ActUser *user,
238 GParamSpec *pspec,
239 ActUserManager *manager);
240 static void give_up (ActUserManager *manager,
241 ActUserManagerFetchUserRequest *request);
242 static void fetch_user_incrementally (ActUserManagerFetchUserRequest *request);
243
244 static void maybe_set_is_loaded (ActUserManager *manager);
245 static void update_user (ActUserManager *manager,
246 ActUser *user);
247 static gpointer user_manager_object = NULL;
248
249 G_DEFINE_TYPE_WITH_PRIVATE (ActUserManager, act_user_manager, G_TYPE_OBJECT)
250
251 static const GDBusErrorEntry error_entries[] = {
252 { ACT_USER_MANAGER_ERROR_FAILED, "org.freedesktop.Accounts.Error.Failed" },
253 { ACT_USER_MANAGER_ERROR_USER_EXISTS, "org.freedesktop.Accounts.Error.UserExists" },
254 { ACT_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST, "org.freedesktop.Accounts.Error.UserDoesNotExist" },
255 { ACT_USER_MANAGER_ERROR_PERMISSION_DENIED, "org.freedesktop.Accounts.Error.PermissionDenied" },
256 { ACT_USER_MANAGER_ERROR_NOT_SUPPORTED, "org.freedesktop.Accounts.Error.NotSupported" }
257 };
258
259 GQuark
act_user_manager_error_quark(void)260 act_user_manager_error_quark (void)
261 {
262 static volatile gsize ret = 0;
263 if (ret == 0) {
264 g_dbus_error_register_error_domain ("act_user_manager_error",
265 &ret,
266 error_entries,
267 G_N_ELEMENTS (error_entries));
268 }
269
270 return (GQuark) ret;
271 }
272
273 static gboolean
activate_console_kit_session_id(ActUserManager * manager,const char * seat_id,const char * session_id)274 activate_console_kit_session_id (ActUserManager *manager,
275 const char *seat_id,
276 const char *session_id)
277 {
278 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
279 ConsoleKitSeat *proxy;
280 g_autoptr(GError) error = NULL;
281 gboolean res = FALSE;
282
283 proxy = console_kit_seat_proxy_new_sync (priv->connection,
284 G_DBUS_PROXY_FLAGS_NONE,
285 CK_NAME,
286 seat_id,
287 NULL,
288 &error);
289 if (proxy)
290 res = console_kit_seat_call_activate_session_sync (proxy,
291 session_id,
292 NULL,
293 &error);
294
295 if (!res) {
296 g_warning ("Unable to activate session: %s", error->message);
297 return FALSE;
298 }
299
300 return TRUE;
301 }
302
303 #ifdef WITH_SYSTEMD
304 static gboolean
activate_systemd_session_id(ActUserManager * manager,const char * seat_id,const char * session_id)305 activate_systemd_session_id (ActUserManager *manager,
306 const char *seat_id,
307 const char *session_id)
308 {
309 g_autoptr(GDBusConnection) connection = NULL;
310 g_autoptr(GVariant) reply = NULL;
311 g_autoptr(GError) error = NULL;
312
313 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
314 if (connection == NULL) {
315 g_warning ("Unable to activate session: %s", error->message);
316 return FALSE;
317 }
318
319 reply = g_dbus_connection_call_sync (connection,
320 "org.freedesktop.login1",
321 "/org/freedesktop/login1",
322 "org.freedesktop.login1.Manager",
323 "ActivateSessionOnSeat",
324 g_variant_new ("(ss)",
325 seat_id,
326 session_id),
327 NULL,
328 G_DBUS_CALL_FLAGS_NONE,
329 -1,
330 NULL,
331 &error);
332 if (reply == NULL) {
333 g_warning ("Unable to activate session: %s", error->message);
334 return FALSE;
335 }
336
337 return TRUE;
338 }
339 #endif
340
341 static gboolean
_ck_session_is_login_window(ActUserManager * manager,const char * session_id)342 _ck_session_is_login_window (ActUserManager *manager,
343 const char *session_id)
344 {
345 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
346 ConsoleKitSession *proxy;
347 g_autoptr(GError) error = NULL;
348 g_autofree gchar *session_type = NULL;
349 gboolean res = FALSE;
350
351 proxy = console_kit_session_proxy_new_sync (priv->connection,
352 G_DBUS_PROXY_FLAGS_NONE,
353 CK_NAME,
354 session_id,
355 NULL,
356 &error);
357 if (proxy)
358 res = console_kit_session_call_get_session_type_sync (proxy, &session_type, NULL, &error);
359
360 if (!res) {
361 if (error != NULL) {
362 g_debug ("ActUserManager: Failed to identify the session type: %s", error->message);
363 } else {
364 g_debug ("ActUserManager: Failed to identify the session type");
365 }
366 return FALSE;
367 }
368 if (proxy)
369 g_object_unref (proxy);
370
371 return strcmp (session_type, "LoginWindow") == 0;
372 }
373
374 #ifdef WITH_SYSTEMD
375 static gboolean
_systemd_session_is_login_window(ActUserManager * manager,const char * session_id)376 _systemd_session_is_login_window (ActUserManager *manager,
377 const char *session_id)
378 {
379 int res;
380 g_autofree gchar *session_class = NULL;
381
382 res = sd_session_get_class (session_id, &session_class);
383 if (res < 0) {
384 g_debug ("failed to determine class of session %s: %s",
385 session_id,
386 strerror (-res));
387 return FALSE;
388 }
389
390 return g_strcmp0 (session_class, "greeter") == 0;
391 }
392 #endif
393
394 static gboolean
session_is_login_window(ActUserManager * manager,const char * session_id)395 session_is_login_window (ActUserManager *manager,
396 const char *session_id)
397 {
398 #ifdef WITH_SYSTEMD
399 if (LOGIND_RUNNING()) {
400 return _systemd_session_is_login_window (manager, session_id);
401 }
402 #endif
403
404 return _ck_session_is_login_window (manager, session_id);
405 }
406
407 static gboolean
_ck_session_is_on_our_seat(ActUserManager * manager,const char * session_id)408 _ck_session_is_on_our_seat (ActUserManager *manager,
409 const char *session_id)
410 {
411 /* With ConsoleKit, we only ever see sessions on our seat. */
412 return TRUE;
413 }
414
415 #ifdef WITH_SYSTEMD
416 static gboolean
_systemd_session_is_on_our_seat(ActUserManager * manager,const char * session_id)417 _systemd_session_is_on_our_seat (ActUserManager *manager,
418 const char *session_id)
419 {
420 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
421 int res;
422 g_autofree gchar *session_seat = NULL;
423
424 res = sd_session_get_seat (session_id, &session_seat);
425 if (res == -ENODATA) {
426 return FALSE;
427 } else if (res < 0) {
428 g_debug ("failed to determine seat of session %s: %s",
429 session_id,
430 strerror (-res));
431 return FALSE;
432 }
433
434 return g_strcmp0 (priv->seat.id, session_seat) == 0;
435 }
436 #endif
437
438 static gboolean
session_is_on_our_seat(ActUserManager * manager,const char * session_id)439 session_is_on_our_seat (ActUserManager *manager,
440 const char *session_id)
441 {
442 #ifdef WITH_SYSTEMD
443 if (LOGIND_RUNNING()) {
444 return _systemd_session_is_on_our_seat (manager, session_id);
445 }
446 #endif
447
448 return _ck_session_is_on_our_seat (manager, session_id);
449 }
450
451 /**
452 * act_user_manager_goto_login_session:
453 * @manager: the user manager
454 *
455 * Switch the display to the login manager.
456 *
457 * Returns: whether successful or not
458 */
459 gboolean
act_user_manager_goto_login_session(ActUserManager * manager)460 act_user_manager_goto_login_session (ActUserManager *manager)
461 {
462 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
463 gboolean res;
464 g_autoptr(GError) error = NULL;
465
466 g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), FALSE);
467 g_return_val_if_fail (priv->is_loaded, FALSE);
468
469 res = g_spawn_command_line_async ("gdmflexiserver", &error);
470 if (!res) {
471 if (error != NULL) {
472 g_warning ("Unable to start new login: %s", error->message);
473 } else {
474 g_warning ("Unable to start new login");
475 }
476 }
477
478 return res;
479
480 }
481
482 #ifdef WITH_SYSTEMD
483 static gboolean
_can_activate_systemd_sessions(ActUserManager * manager)484 _can_activate_systemd_sessions (ActUserManager *manager)
485 {
486 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
487 int res;
488
489 res = sd_seat_can_multi_session (priv->seat.id);
490 if (res < 0) {
491 g_warning ("unable to determine if seat %s can activate sessions: %s",
492 priv->seat.id, strerror (-res));
493 return FALSE;
494 }
495
496 return res > 0;
497 }
498 #endif
499
500 gboolean
_can_activate_console_kit_sessions(ActUserManager * manager)501 _can_activate_console_kit_sessions (ActUserManager *manager)
502 {
503 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
504 g_autoptr(GError) error = NULL;
505 gboolean can_activate_sessions = FALSE;
506
507 if (!console_kit_seat_call_can_activate_sessions_sync (priv->seat.seat_proxy, &can_activate_sessions, NULL, &error)) {
508 if (error != NULL) {
509 g_warning ("unable to determine if seat can activate sessions: %s",
510 error->message);
511 } else {
512 g_warning ("unable to determine if seat can activate sessions");
513 }
514 return FALSE;
515 }
516
517 return can_activate_sessions;
518 }
519
520 /**
521 * act_user_manager_can_switch:
522 * @manager: the user manager
523 *
524 * Check whether the user can switch to another session.
525 *
526 * Returns: whether we can switch to another session
527 */
528 gboolean
act_user_manager_can_switch(ActUserManager * manager)529 act_user_manager_can_switch (ActUserManager *manager)
530 {
531 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
532
533 if (!priv->is_loaded) {
534 g_debug ("ActUserManager: Unable to switch sessions until fully loaded");
535 return FALSE;
536 }
537
538 if (priv->seat.id == NULL || priv->seat.id[0] == '\0') {
539 g_debug ("ActUserManager: display seat ID is not set; can't switch sessions");
540 return FALSE;
541 }
542
543 g_debug ("ActUserManager: checking if seat can activate sessions");
544
545
546 #ifdef WITH_SYSTEMD
547 if (LOGIND_RUNNING()) {
548 return _can_activate_systemd_sessions (manager);
549 }
550 #endif
551
552 return _can_activate_console_kit_sessions (manager);
553 }
554
555 /**
556 * act_user_manager_activate_user_session:
557 * @manager: the user manager
558 * @user: the user to activate
559 *
560 * Activate the session for a given user.
561 *
562 * Returns: whether successfully activated
563 */
564 gboolean
act_user_manager_activate_user_session(ActUserManager * manager,ActUser * user)565 act_user_manager_activate_user_session (ActUserManager *manager,
566 ActUser *user)
567 {
568 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
569 gboolean can_activate_sessions;
570 const char *ssid;
571
572 g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), FALSE);
573 g_return_val_if_fail (ACT_IS_USER (user), FALSE);
574 g_return_val_if_fail (priv->is_loaded, FALSE);
575
576 can_activate_sessions = act_user_manager_can_switch (manager);
577
578 if (!can_activate_sessions) {
579 g_debug ("ActUserManager: seat is unable to activate sessions");
580 return FALSE;
581 }
582
583 ssid = act_user_get_primary_session_id (user);
584 if (ssid == NULL) {
585 return FALSE;
586 }
587
588 #ifdef WITH_SYSTEMD
589 if (LOGIND_RUNNING()) {
590 return activate_systemd_session_id (manager, priv->seat.id, ssid);
591 }
592 #endif
593
594 if (!activate_console_kit_session_id (manager, priv->seat.id, ssid)) {
595 g_debug ("ActUserManager: unable to activate session: %s", ssid);
596 return FALSE;
597 }
598
599 return TRUE;
600 }
601
602 static const char *
describe_user(ActUser * user)603 describe_user (ActUser *user)
604 {
605 ActUserManagerFetchUserRequest *request;
606
607 if (act_user_is_loaded (user)) {
608 static char *description = NULL;
609 g_clear_pointer (&description, (GDestroyNotify) g_free);
610
611 description = g_strdup_printf ("user %s", act_user_get_user_name (user));
612 return description;
613 }
614
615 request = g_object_get_data (G_OBJECT (user), "fetch-user-request");
616
617 if (request != NULL) {
618 return request->description;
619 }
620
621 return "user";
622 }
623
624 static void
on_user_sessions_changed(ActUser * user,ActUserManager * manager)625 on_user_sessions_changed (ActUser *user,
626 ActUserManager *manager)
627 {
628 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
629 guint nsessions;
630
631 if (!priv->is_loaded) {
632 return;
633 }
634
635 nsessions = act_user_get_num_sessions (user);
636
637 g_debug ("ActUserManager: sessions changed (%s) num=%d",
638 describe_user (user),
639 nsessions);
640
641 /* only signal on zero and one */
642 if (nsessions > 1) {
643 return;
644 }
645
646 g_signal_emit (manager, signals [USER_IS_LOGGED_IN_CHANGED], 0, user);
647 }
648
649 static void
on_user_changed(ActUser * user,ActUserManager * manager)650 on_user_changed (ActUser *user,
651 ActUserManager *manager)
652 {
653 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
654
655 if (priv->is_loaded) {
656 g_debug ("ActUserManager: sending user-changed signal for %s",
657 describe_user (user));
658
659 g_signal_emit (manager, signals[USER_CHANGED], 0, user);
660
661 g_debug ("ActUserManager: sent user-changed signal for %s",
662 describe_user (user));
663
664 update_user (manager, user);
665 }
666 }
667
668 static void
queue_load_seat_incrementally(ActUserManager * manager)669 queue_load_seat_incrementally (ActUserManager *manager)
670 {
671 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
672
673 if (priv->seat.load_idle_id == 0) {
674 priv->seat.load_idle_id = g_idle_add ((GSourceFunc) load_seat_incrementally, manager);
675 }
676 }
677
678 static void
on_get_seat_id_finished(GObject * object,GAsyncResult * result,gpointer data)679 on_get_seat_id_finished (GObject *object,
680 GAsyncResult *result,
681 gpointer data)
682 {
683 ConsoleKitSession *proxy = CONSOLE_KIT_SESSION (object);
684 g_autoptr(ActUserManager) manager = data;
685 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
686 g_autoptr(GError) error = NULL;
687 char *seat_id;
688
689 if (!console_kit_session_call_get_seat_id_finish (proxy, &seat_id, result, &error)) {
690 if (error != NULL) {
691 g_debug ("Failed to identify the seat of the "
692 "current session: %s",
693 error->message);
694 } else {
695 g_debug ("Failed to identify the seat of the "
696 "current session");
697 }
698
699 g_debug ("ActUserManager: GetSeatId call failed, so unloading seat");
700 unload_seat (manager);
701
702 return;
703 }
704
705 g_debug ("ActUserManager: Found current seat: %s", seat_id);
706
707 priv->seat.id = seat_id;
708 priv->seat.state++;
709 }
710
711 #ifdef WITH_SYSTEMD
712 static gboolean
_systemd_session_is_graphical(const char * session_id)713 _systemd_session_is_graphical (const char *session_id)
714 {
715 const gchar * const graphical_session_types[] = { "wayland", "x11", "mir", NULL };
716 int saved_errno;
717 g_autofree gchar *type = NULL;
718
719 saved_errno = sd_session_get_type (session_id, &type);
720 if (saved_errno < 0) {
721 g_warning ("Couldn't get type for session '%s': %s",
722 session_id,
723 g_strerror (-saved_errno));
724 return FALSE;
725 }
726
727 if (!g_strv_contains (graphical_session_types, type)) {
728 g_debug ("Session '%s' is not a graphical session (type: '%s')",
729 session_id,
730 type);
731 return FALSE;
732 }
733
734 return TRUE;
735 }
736
737 static gboolean
_systemd_session_is_active(const char * session_id)738 _systemd_session_is_active (const char *session_id)
739 {
740 const gchar * const active_states[] = { "active", "online", NULL };
741 int saved_errno;
742 g_autofree gchar *state = NULL;
743
744 /*
745 * display sessions can be 'closing' if they are logged out but some
746 * processes are lingering; we shouldn't consider these (this is
747 * checking for a race condition since we specified that we want online
748 * sessions only)
749 */
750 saved_errno = sd_session_get_state (session_id, &state);
751 if (saved_errno < 0) {
752 g_warning ("Couldn't get state for session '%s': %s",
753 session_id,
754 g_strerror (-saved_errno));
755 return FALSE;
756 }
757
758 if (!g_strv_contains (active_states, state)) {
759 g_debug ("Session '%s' is not active or online", session_id);
760 return FALSE;
761 }
762
763 return TRUE;
764 }
765
766 static gboolean
_find_graphical_systemd_session(char ** session_id)767 _find_graphical_systemd_session (char **session_id)
768 {
769 char *local_session_id = NULL;
770 g_auto(GStrv) sessions = NULL;
771 int n_sessions;
772
773 /* filter level 0 means to include inactive and active sessions
774 * (>0 would mean to return only the active session, and <0 would mean to
775 * include closing sessions too)
776 */
777 static int filter_level = 0;
778
779 g_return_val_if_fail (session_id != NULL, FALSE);
780
781 g_debug ("Finding a graphical session for user %d", getuid ());
782
783 n_sessions = sd_uid_get_sessions (getuid (), filter_level, &sessions);
784
785 if (n_sessions < 0) {
786 g_critical ("Failed to get sessions for user %d", getuid ());
787 return FALSE;
788 }
789
790 for (int i = 0; i < n_sessions; ++i) {
791 g_debug ("Considering session '%s'", sessions[i]);
792
793 if (!_systemd_session_is_graphical (sessions[i]))
794 continue;
795
796 if (!_systemd_session_is_active (sessions[i]))
797 continue;
798
799 /*
800 * We get the sessions from newest to oldest, so take the last
801 * one we find that's good
802 */
803 local_session_id = sessions[i];
804 }
805
806 if (local_session_id == NULL)
807 return FALSE;
808
809 *session_id = g_strdup (local_session_id);
810
811 return TRUE;
812 }
813
814 static void
_get_systemd_seat_id(ActUserManager * manager)815 _get_systemd_seat_id (ActUserManager *manager)
816 {
817 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
818 int res;
819 g_autofree gchar *seat_id = NULL;
820
821 if (priv->seat.session_id == NULL) {
822 if (!_find_graphical_systemd_session (&priv->seat.session_id)) {
823 g_warning ("Could not get session");
824 return;
825 }
826 }
827
828 res = sd_session_get_seat (priv->seat.session_id, &seat_id);
829
830 if (res == -ENODATA) {
831 seat_id = NULL;
832 } else if (res < 0) {
833 g_warning ("Could not get current seat: %s",
834 strerror (-res));
835 unload_seat (manager);
836 return;
837 }
838
839 priv->seat.id = g_strdup (seat_id);
840 priv->seat.state++;
841 }
842 #endif
843
844 static void
get_seat_id_for_current_session(ActUserManager * manager)845 get_seat_id_for_current_session (ActUserManager *manager)
846 {
847 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
848
849 #ifdef WITH_SYSTEMD
850 if (LOGIND_RUNNING()) {
851 _get_systemd_seat_id (manager);
852 return;
853 }
854 #endif
855 console_kit_session_call_get_seat_id (priv->seat.session_proxy,
856 NULL,
857 on_get_seat_id_finished,
858 g_object_ref (manager));
859 }
860
861 static gint
match_name_cmpfunc(gconstpointer a,gconstpointer b)862 match_name_cmpfunc (gconstpointer a,
863 gconstpointer b)
864 {
865 return g_strcmp0 ((char *) a,
866 (char *) b);
867 }
868
869 static gboolean
username_in_exclude_list(ActUserManager * manager,const char * username)870 username_in_exclude_list (ActUserManager *manager,
871 const char *username)
872 {
873 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
874 GSList *found;
875 gboolean ret = FALSE;
876
877 if (priv->exclude_usernames != NULL) {
878 found = g_slist_find_custom (priv->exclude_usernames,
879 username,
880 match_name_cmpfunc);
881 if (found != NULL) {
882 ret = TRUE;
883 }
884 }
885
886 return ret;
887 }
888
889 static void
add_session_for_user(ActUserManager * manager,ActUser * user,const char * ssid,gboolean is_ours)890 add_session_for_user (ActUserManager *manager,
891 ActUser *user,
892 const char *ssid,
893 gboolean is_ours)
894 {
895 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
896
897 g_hash_table_insert (priv->sessions,
898 g_strdup (ssid),
899 g_object_ref (user));
900
901 _act_user_add_session (user, ssid, is_ours);
902 g_debug ("ActUserManager: added session for %s", describe_user (user));
903 }
904
905 static void
set_has_multiple_users(ActUserManager * manager,gboolean has_multiple_users)906 set_has_multiple_users (ActUserManager *manager,
907 gboolean has_multiple_users)
908 {
909 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
910
911 if (priv->has_multiple_users != has_multiple_users) {
912 priv->has_multiple_users = has_multiple_users;
913 g_object_notify (G_OBJECT (manager), "has-multiple-users");
914 }
915 }
916
917 static ActUser *
create_new_user(ActUserManager * manager)918 create_new_user (ActUserManager *manager)
919 {
920 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
921 ActUser *user;
922
923 user = g_object_new (ACT_TYPE_USER, NULL);
924
925 priv->new_users = g_slist_prepend (priv->new_users, g_object_ref (user));
926
927 g_signal_connect_object (user, "notify::is-loaded", G_CALLBACK (on_new_user_loaded), manager, 0);
928
929 return user;
930 }
931
932 static void
add_user(ActUserManager * manager,ActUser * user)933 add_user (ActUserManager *manager,
934 ActUser *user)
935 {
936 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
937 const char *object_path;
938
939 g_debug ("ActUserManager: tracking user '%s'", act_user_get_user_name (user));
940 if (act_user_is_system_account (user)) {
941 g_hash_table_insert (priv->system_users_by_name,
942 g_strdup (act_user_get_user_name (user)),
943 g_object_ref (user));
944 } else {
945 g_hash_table_insert (priv->normal_users_by_name,
946 g_strdup (act_user_get_user_name (user)),
947 g_object_ref (user));
948 }
949
950 object_path = act_user_get_object_path (user);
951 if (object_path != NULL) {
952 g_hash_table_replace (priv->users_by_object_path,
953 (gpointer) object_path,
954 g_object_ref (user));
955 }
956
957 g_signal_connect_object (user,
958 "sessions-changed",
959 G_CALLBACK (on_user_sessions_changed),
960 manager, 0);
961 g_signal_connect_object (user,
962 "changed",
963 G_CALLBACK (on_user_changed),
964 manager, 0);
965
966 if (priv->is_loaded && priv->list_cached_users_done) {
967 g_debug ("ActUserManager: loaded, so emitting user-added signal");
968 g_signal_emit (manager, signals[USER_ADDED], 0, user);
969 } else {
970 g_debug ("ActUserManager: not yet loaded, so not emitting user-added signal");
971 }
972 }
973
974 static void
remove_user(ActUserManager * manager,ActUser * user)975 remove_user (ActUserManager *manager,
976 ActUser *user)
977 {
978 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
979
980 g_debug ("ActUserManager: no longer tracking user '%s' (with object path %s)",
981 act_user_get_user_name (user),
982 act_user_get_object_path (user));
983
984 g_object_ref (user);
985
986 g_signal_handlers_disconnect_by_func (user, on_user_changed, manager);
987 g_signal_handlers_disconnect_by_func (user, on_user_sessions_changed, manager);
988 if (act_user_get_object_path (user) != NULL) {
989 g_hash_table_remove (priv->users_by_object_path, act_user_get_object_path (user));
990 }
991 if (act_user_get_user_name (user) != NULL) {
992 g_hash_table_remove (priv->normal_users_by_name, act_user_get_user_name (user));
993 g_hash_table_remove (priv->system_users_by_name, act_user_get_user_name (user));
994
995 }
996
997 if (priv->is_loaded && priv->list_cached_users_done) {
998 g_debug ("ActUserManager: loaded, so emitting user-removed signal");
999 g_signal_emit (manager, signals[USER_REMOVED], 0, user);
1000 } else {
1001 g_debug ("ActUserManager: not yet loaded, so not emitting user-removed signal");
1002 }
1003
1004 g_debug ("ActUserManager: user '%s' (with object path %s) now removed",
1005 act_user_get_user_name (user),
1006 act_user_get_object_path (user));
1007 g_object_unref (user);
1008 }
1009
1010 static void
update_user(ActUserManager * manager,ActUser * user)1011 update_user (ActUserManager *manager,
1012 ActUser *user)
1013 {
1014 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1015 const char *username;
1016
1017 g_debug ("ActUserManager: updating %s", describe_user (user));
1018
1019 username = act_user_get_user_name (user);
1020 if (g_hash_table_lookup (priv->system_users_by_name, username) != NULL) {
1021 if (!act_user_is_system_account (user)) {
1022 g_debug ("ActUserManager: %s is no longer a system account, treating as normal user",
1023 describe_user (user));
1024 g_hash_table_insert (priv->normal_users_by_name,
1025 g_strdup (act_user_get_user_name (user)),
1026 g_object_ref (user));
1027 g_hash_table_remove (priv->system_users_by_name, username);
1028 g_signal_emit (manager, signals[USER_ADDED], 0, user);
1029 }
1030 } else {
1031 if (act_user_is_system_account (user)) {
1032 g_debug ("ActUserManager: %s is no longer a normal account, treating as system user",
1033 describe_user (user));
1034 g_hash_table_insert (priv->system_users_by_name,
1035 g_strdup (act_user_get_user_name (user)),
1036 g_object_ref (user));
1037 g_hash_table_remove (priv->normal_users_by_name, username);
1038 g_signal_emit (manager, signals[USER_REMOVED], 0, user);
1039 }
1040 }
1041 }
1042
1043 static ActUser *
lookup_user_by_name(ActUserManager * manager,const char * username)1044 lookup_user_by_name (ActUserManager *manager,
1045 const char *username)
1046 {
1047 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1048 ActUser *user;
1049
1050 user = g_hash_table_lookup (priv->normal_users_by_name, username);
1051
1052 if (user == NULL) {
1053 user = g_hash_table_lookup (priv->system_users_by_name, username);
1054 }
1055
1056 return user;
1057 }
1058
1059 static void
on_new_user_loaded(ActUser * user,GParamSpec * pspec,ActUserManager * manager)1060 on_new_user_loaded (ActUser *user,
1061 GParamSpec *pspec,
1062 ActUserManager *manager)
1063 {
1064 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1065 const char *username;
1066 ActUser *old_user;
1067
1068 if (!act_user_is_loaded (user)) {
1069 g_debug ("ActUserManager: %s loaded function called when not loaded",
1070 describe_user (user));
1071 return;
1072 }
1073 g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
1074
1075 priv->new_users = g_slist_remove (priv->new_users,
1076 user);
1077 priv->new_users_inhibiting_load = g_slist_remove (priv->new_users_inhibiting_load,
1078 user);
1079
1080 username = act_user_get_user_name (user);
1081
1082 if (username == NULL) {
1083 const char *object_path;
1084
1085 object_path = act_user_get_object_path (user);
1086
1087 if (object_path != NULL) {
1088 g_warning ("ActUserManager: %s has no username "
1089 "(object path: %s, uid: %d)",
1090 describe_user (user),
1091 object_path, (int) act_user_get_uid (user));
1092 } else {
1093 g_warning ("ActUserManager: %s has no username (uid: %d)",
1094 describe_user (user),
1095 (int) act_user_get_uid (user));
1096 }
1097 g_object_unref (user);
1098 goto out;
1099 }
1100
1101 g_debug ("ActUserManager: %s is now loaded", describe_user (user));
1102
1103 if (username_in_exclude_list (manager, username)) {
1104 g_debug ("ActUserManager: excluding user '%s'", username);
1105 g_object_unref (user);
1106 goto out;
1107 }
1108
1109 old_user = lookup_user_by_name (manager, username);
1110
1111 /* If username hasn't been added, yet, add it now
1112 */
1113 if (old_user == NULL) {
1114 g_debug ("ActUserManager: %s was not yet known, adding it",
1115 describe_user (user));
1116 add_user (manager, user);
1117 } else {
1118 _act_user_load_from_user (old_user, user);
1119 }
1120
1121 g_object_unref (user);
1122
1123 out:
1124 if (priv->new_users_inhibiting_load == NULL) {
1125 g_debug ("ActUserManager: no pending users, trying to set loaded property");
1126 maybe_set_is_loaded (manager);
1127 } else {
1128 g_debug ("ActUserManager: not all users loaded yet");
1129 }
1130 }
1131
1132 static ActUser *
find_new_user_with_object_path(ActUserManager * manager,const char * object_path)1133 find_new_user_with_object_path (ActUserManager *manager,
1134 const char *object_path)
1135 {
1136 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1137 GSList *node;
1138
1139 g_assert (object_path != NULL);
1140
1141 for (node = priv->new_users; node != NULL; node = node->next) {
1142 ActUser *user = ACT_USER (node->data);
1143 const char *user_object_path = act_user_get_object_path (user);
1144 if (g_strcmp0 (user_object_path, object_path) == 0) {
1145 return user;
1146 }
1147 }
1148
1149 return NULL;
1150 }
1151
1152 static ActUser *
add_new_user_for_object_path(const char * object_path,ActUserManager * manager)1153 add_new_user_for_object_path (const char *object_path,
1154 ActUserManager *manager)
1155 {
1156 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1157 ActUser *user;
1158
1159 user = g_hash_table_lookup (priv->users_by_object_path, object_path);
1160
1161 if (user != NULL) {
1162 g_debug ("ActUserManager: tracking existing %s with object path %s",
1163 describe_user (user), object_path);
1164 return user;
1165 }
1166
1167 user = find_new_user_with_object_path (manager, object_path);
1168
1169 if (user != NULL) {
1170 g_debug ("ActUserManager: tracking existing (but very recently added) %s with object path %s",
1171 describe_user (user), object_path);
1172 return user;
1173 }
1174
1175 g_debug ("ActUserManager: tracking new user with object path %s", object_path);
1176
1177 user = create_new_user (manager);
1178 _act_user_update_from_object_path (user, object_path);
1179
1180 return user;
1181 }
1182
1183 static void
on_new_user_in_accounts_service(GDBusProxy * proxy,const char * object_path,gpointer user_data)1184 on_new_user_in_accounts_service (GDBusProxy *proxy,
1185 const char *object_path,
1186 gpointer user_data)
1187 {
1188 ActUserManager *manager = ACT_USER_MANAGER (user_data);
1189 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1190 g_autoptr(ActUser) user = NULL;
1191
1192 /* Only track user changes if the user has requested a list
1193 * of users */
1194 if (!priv->list_cached_users_done) {
1195 return;
1196 }
1197
1198 if (!priv->is_loaded) {
1199 g_debug ("ActUserManager: ignoring new user in accounts service with object path %s since not loaded yet", object_path);
1200 return;
1201 }
1202
1203 g_debug ("ActUserManager: new user in accounts service with object path %s", object_path);
1204 user = add_new_user_for_object_path (object_path, manager);
1205 }
1206
1207 static void
on_user_removed_in_accounts_service(GDBusProxy * proxy,const char * object_path,gpointer user_data)1208 on_user_removed_in_accounts_service (GDBusProxy *proxy,
1209 const char *object_path,
1210 gpointer user_data)
1211 {
1212 ActUserManager *manager = ACT_USER_MANAGER (user_data);
1213 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1214 ActUser *user;
1215 GSList *node;
1216
1217 /* Only track user changes if the user has requested a list
1218 * of users */
1219 if (!priv->list_cached_users_done) {
1220 return;
1221 }
1222
1223 user = g_hash_table_lookup (priv->users_by_object_path, object_path);
1224
1225 if (user == NULL) {
1226 g_debug ("ActUserManager: ignoring untracked user %s", object_path);
1227 return;
1228 } else {
1229 g_debug ("ActUserManager: tracked user %s removed from accounts service", object_path);
1230 }
1231
1232 node = g_slist_find (priv->new_users, user);
1233 if (node != NULL) {
1234 g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
1235 g_object_unref (user);
1236 priv->new_users = g_slist_delete_link (priv->new_users, node);
1237 }
1238
1239 remove_user (manager, user);
1240 }
1241
1242 static void
on_get_current_session_finished(GObject * object,GAsyncResult * result,gpointer data)1243 on_get_current_session_finished (GObject *object,
1244 GAsyncResult *result,
1245 gpointer data)
1246 {
1247 ConsoleKitManager *proxy = CONSOLE_KIT_MANAGER (object);
1248 g_autoptr(ActUserManager) manager = data;
1249 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1250 g_autoptr(GError) error = NULL;
1251 char *session_id;
1252
1253 g_assert (priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_ID);
1254
1255 if (!console_kit_manager_call_get_current_session_finish (proxy, &session_id, result, &error)) {
1256 if (error != NULL) {
1257 g_debug ("Failed to identify the current session: %s",
1258 error->message);
1259 } else {
1260 g_debug ("Failed to identify the current session");
1261 }
1262 unload_seat (manager);
1263
1264 return;
1265 }
1266
1267 priv->seat.session_id = session_id;
1268 priv->seat.state++;
1269
1270 queue_load_seat_incrementally (manager);
1271 }
1272
1273 #ifdef WITH_SYSTEMD
1274 static void
_get_current_systemd_session_id(ActUserManager * manager)1275 _get_current_systemd_session_id (ActUserManager *manager)
1276 {
1277 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1278 g_autofree gchar *session_id = NULL;
1279
1280 if (!_find_graphical_systemd_session (&session_id)) {
1281 g_debug ("Failed to identify the current session");
1282 unload_seat (manager);
1283 return;
1284 }
1285
1286 priv->seat.session_id = g_strdup (session_id);
1287 priv->seat.state++;
1288
1289 queue_load_seat_incrementally (manager);
1290
1291 }
1292 #endif
1293
1294 static void
get_current_session_id(ActUserManager * manager)1295 get_current_session_id (ActUserManager *manager)
1296 {
1297 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1298
1299 #ifdef WITH_SYSTEMD
1300 if (LOGIND_RUNNING()) {
1301 _get_current_systemd_session_id (manager);
1302 return;
1303 }
1304 #endif
1305
1306 if (priv->ck_manager_proxy == NULL) {
1307 g_autoptr(GError) error = NULL;
1308
1309 priv->ck_manager_proxy = console_kit_manager_proxy_new_sync (priv->connection,
1310 G_DBUS_PROXY_FLAGS_NONE,
1311 CK_NAME,
1312 CK_MANAGER_PATH,
1313 NULL,
1314 &error);
1315 if (priv->ck_manager_proxy == NULL) {
1316 if (error != NULL) {
1317 g_warning ("Failed to create ConsoleKit proxy: %s", error->message);
1318 } else {
1319 g_warning ("Failed to create_ConsoleKit_proxy");
1320 }
1321 unload_seat (manager);
1322 return;
1323 }
1324 }
1325
1326 console_kit_manager_call_get_current_session (priv->ck_manager_proxy, NULL,
1327 on_get_current_session_finished,
1328 g_object_ref (manager));
1329 }
1330
1331 static void
unload_new_session(ActUserManagerNewSession * new_session)1332 unload_new_session (ActUserManagerNewSession *new_session)
1333 {
1334 ActUserManager *manager = new_session->manager;
1335 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1336
1337 /* From here down to the check on pending_calls is idempotent,
1338 * like GObject dispose(); it can be called twice if the new session
1339 * is unloaded while there are still async calls pending.
1340 */
1341
1342 if (new_session->cancellable != NULL &&
1343 !g_cancellable_is_cancelled (new_session->cancellable)) {
1344 g_cancellable_cancel (new_session->cancellable);
1345 g_object_unref (new_session->cancellable);
1346 new_session->cancellable = NULL;
1347 }
1348
1349 if (new_session->proxy != NULL) {
1350 g_object_unref (new_session->proxy);
1351 new_session->proxy = NULL;
1352 }
1353
1354 g_free (new_session->x11_display);
1355 new_session->x11_display = NULL;
1356 g_free (new_session->id);
1357 new_session->id = NULL;
1358
1359 if (manager != NULL) {
1360 priv->new_sessions = g_slist_remove (priv->new_sessions,
1361 new_session);
1362
1363 g_debug ("ActUserManager: unrefing manager owned by new session that's now unloaded");
1364 new_session->manager = NULL;
1365 g_object_unref (manager);
1366 }
1367
1368 if (new_session->pending_calls != 0) {
1369 /* don't "finalize" until we run out of pending calls
1370 * that have us as their user_data */
1371 return;
1372 }
1373
1374 g_slice_free (ActUserManagerNewSession, new_session);
1375 }
1376
1377 static void
get_proxy_for_new_session(ActUserManagerNewSession * new_session)1378 get_proxy_for_new_session (ActUserManagerNewSession *new_session)
1379 {
1380 ActUserManager *manager = new_session->manager;
1381 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1382 g_autoptr(GError) error = NULL;
1383
1384 #ifdef WITH_SYSTEMD
1385 if (LOGIND_RUNNING()) {
1386 new_session->state++;
1387 load_new_session_incrementally (new_session);
1388 return;
1389 }
1390 #endif
1391
1392 new_session->proxy = console_kit_session_proxy_new_sync (priv->connection,
1393 G_DBUS_PROXY_FLAGS_NONE,
1394 CK_NAME,
1395 new_session->id,
1396 NULL,
1397 &error);
1398 if (new_session->proxy == NULL) {
1399 g_warning ("Failed to connect to the ConsoleKit '%s' object: %s",
1400 new_session->id, error->message);
1401 unload_new_session (new_session);
1402 return;
1403 }
1404
1405 new_session->state++;
1406
1407 load_new_session_incrementally (new_session);
1408 }
1409
1410 static void
on_get_unix_user_finished(GObject * object,GAsyncResult * result,gpointer data)1411 on_get_unix_user_finished (GObject *object,
1412 GAsyncResult *result,
1413 gpointer data)
1414 {
1415 ConsoleKitSession *proxy = CONSOLE_KIT_SESSION (object);
1416 ActUserManagerNewSession *new_session = data;
1417 g_autoptr(GError) error = NULL;
1418 guint uid;
1419
1420 new_session->pending_calls--;
1421
1422 if (new_session->cancellable == NULL || g_cancellable_is_cancelled (new_session->cancellable)) {
1423 unload_new_session (new_session);
1424 return;
1425 }
1426
1427 if (!console_kit_session_call_get_unix_user_finish (proxy, &uid, result, &error)) {
1428 if (error != NULL) {
1429 g_debug ("Failed to get uid of session '%s': %s",
1430 new_session->id, error->message);
1431 } else {
1432 g_debug ("Failed to get uid of session '%s'",
1433 new_session->id);
1434 }
1435 unload_new_session (new_session);
1436 return;
1437 }
1438
1439 g_debug ("ActUserManager: Found uid of session '%s': %u",
1440 new_session->id, uid);
1441
1442 new_session->uid = (uid_t) uid;
1443 new_session->state++;
1444
1445 load_new_session_incrementally (new_session);
1446 }
1447
1448 #ifdef WITH_SYSTEMD
1449 static void
_get_uid_for_new_systemd_session(ActUserManagerNewSession * new_session)1450 _get_uid_for_new_systemd_session (ActUserManagerNewSession *new_session)
1451 {
1452 uid_t uid;
1453 int res;
1454
1455 res = sd_session_get_uid (new_session->id, &uid);
1456
1457 if (res < 0) {
1458 g_debug ("Failed to get uid of session '%s': %s",
1459 new_session->id,
1460 strerror (-res));
1461 unload_new_session (new_session);
1462 return;
1463 }
1464
1465 new_session->uid = uid;
1466 new_session->state++;
1467
1468 load_new_session_incrementally (new_session);
1469 }
1470 #endif
1471
1472 static void
get_uid_for_new_session(ActUserManagerNewSession * new_session)1473 get_uid_for_new_session (ActUserManagerNewSession *new_session)
1474 {
1475 #ifdef WITH_SYSTEMD
1476 if (LOGIND_RUNNING()) {
1477 _get_uid_for_new_systemd_session (new_session);
1478 return;
1479 }
1480 #endif
1481
1482 g_assert (new_session->proxy != NULL);
1483
1484 new_session->pending_calls++;
1485 console_kit_session_call_get_unix_user (new_session->proxy,
1486 new_session->cancellable,
1487 on_get_unix_user_finished,
1488 new_session);
1489 }
1490
1491 static void
on_find_user_by_name_finished(GObject * object,GAsyncResult * result,gpointer data)1492 on_find_user_by_name_finished (GObject *object,
1493 GAsyncResult *result,
1494 gpointer data)
1495 {
1496 AccountsAccounts *proxy = ACCOUNTS_ACCOUNTS (object);
1497 ActUserManagerFetchUserRequest *request = data;
1498 g_autoptr(GError) error = NULL;
1499 char *user;
1500
1501 if (!accounts_accounts_call_find_user_by_name_finish (proxy, &user, result, &error)) {
1502 if (error != NULL) {
1503 g_debug ("ActUserManager: Failed to find %s: %s",
1504 request->description, error->message);
1505 } else {
1506 g_debug ("ActUserManager: Failed to find %s",
1507 request->description);
1508 }
1509 give_up (request->manager, request);
1510 return;
1511 }
1512
1513 g_debug ("ActUserManager: Found object path of %s: %s",
1514 request->description, user);
1515 request->object_path = user;
1516 request->state++;
1517
1518 fetch_user_incrementally (request);
1519 }
1520
1521 static void
on_find_user_by_id_finished(GObject * object,GAsyncResult * result,gpointer data)1522 on_find_user_by_id_finished (GObject *object,
1523 GAsyncResult *result,
1524 gpointer data)
1525 {
1526 AccountsAccounts *proxy = ACCOUNTS_ACCOUNTS (object);
1527 ActUserManagerFetchUserRequest *request = data;
1528 g_autoptr(GError) error = NULL;
1529 char *user;
1530
1531 if (!accounts_accounts_call_find_user_by_id_finish (proxy, &user, result, &error)) {
1532 if (error != NULL) {
1533 g_debug ("ActUserManager: Failed to find user %lu: %s",
1534 (gulong) request->uid, error->message);
1535 } else {
1536 g_debug ("ActUserManager: Failed to find user with id %lu",
1537 (gulong) request->uid);
1538 }
1539 give_up (request->manager, request);
1540 return;
1541 }
1542
1543 g_debug ("ActUserManager: Found object path of %s: %s",
1544 request->description, user);
1545 request->object_path = user;
1546 request->state++;
1547
1548 fetch_user_incrementally (request);
1549 }
1550
1551 static void
find_user_in_accounts_service(ActUserManager * manager,ActUserManagerFetchUserRequest * request)1552 find_user_in_accounts_service (ActUserManager *manager,
1553 ActUserManagerFetchUserRequest *request)
1554 {
1555 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1556
1557 g_assert (priv->accounts_proxy != NULL);
1558
1559 g_debug ("ActUserManager: Looking for %s in accounts service",
1560 request->description);
1561
1562 switch (request->type) {
1563 case ACT_USER_MANAGER_FETCH_USER_FROM_USERNAME_REQUEST:
1564 accounts_accounts_call_find_user_by_name (priv->accounts_proxy,
1565 request->username,
1566 NULL,
1567 on_find_user_by_name_finished,
1568 request);
1569 break;
1570 case ACT_USER_MANAGER_FETCH_USER_FROM_ID_REQUEST:
1571 accounts_accounts_call_find_user_by_id (priv->accounts_proxy,
1572 request->uid,
1573 NULL,
1574 on_find_user_by_id_finished,
1575 request);
1576 break;
1577
1578 }
1579 }
1580
1581 static void
set_is_loaded(ActUserManager * manager,gboolean is_loaded)1582 set_is_loaded (ActUserManager *manager,
1583 gboolean is_loaded)
1584 {
1585 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1586
1587 if (priv->is_loaded != is_loaded) {
1588 priv->is_loaded = is_loaded;
1589 g_object_notify (G_OBJECT (manager), "is-loaded");
1590 }
1591 }
1592
1593 static void
load_user_paths(ActUserManager * manager,const char * const * user_paths)1594 load_user_paths (ActUserManager *manager,
1595 const char * const * user_paths)
1596 {
1597 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1598
1599 /* We now have a batch of unloaded users that we know about. Once that initial
1600 * batch is loaded up, we can mark the manager as loaded.
1601 *
1602 * (see on_new_user_loaded)
1603 */
1604 if (g_strv_length ((char **) user_paths) > 0) {
1605 int i;
1606
1607 g_debug ("ActUserManager: ListCachedUsers finished, will set loaded property after list is fully loaded");
1608 for (i = 0; user_paths[i] != NULL; i++) {
1609 ActUser *user;
1610
1611 user = add_new_user_for_object_path (user_paths[i], manager);
1612 if (!priv->is_loaded) {
1613 priv->new_users_inhibiting_load = g_slist_prepend (priv->new_users_inhibiting_load, user);
1614 }
1615 }
1616 } else {
1617 g_debug ("ActUserManager: ListCachedUsers finished with empty list, maybe setting loaded property now");
1618 maybe_set_is_loaded (manager);
1619 }
1620 }
1621
1622 static void
load_included_usernames(ActUserManager * manager)1623 load_included_usernames (ActUserManager *manager)
1624 {
1625 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1626 GSList *l;
1627
1628 /* Add users who are specifically included */
1629 for (l = priv->include_usernames; l != NULL; l = l->next) {
1630 g_debug ("ActUserManager: Adding included user %s", (char *)l->data);
1631
1632 load_user (manager, l->data);
1633 }
1634 }
1635
1636 static void
on_get_x11_display_finished(GObject * object,GAsyncResult * result,gpointer data)1637 on_get_x11_display_finished (GObject *object,
1638 GAsyncResult *result,
1639 gpointer data)
1640 {
1641 ConsoleKitSession *proxy = CONSOLE_KIT_SESSION (object);
1642 ActUserManagerNewSession *new_session = data;
1643 g_autoptr(GError) error = NULL;
1644 char *x11_display;
1645
1646 new_session->pending_calls--;
1647
1648 if (new_session->cancellable == NULL || g_cancellable_is_cancelled (new_session->cancellable)) {
1649 unload_new_session (new_session);
1650 return;
1651 }
1652
1653 if (!console_kit_session_call_get_x11_display_finish (proxy, &x11_display, result, &error)) {
1654 if (error != NULL) {
1655 g_debug ("Failed to get the x11 display of session '%s': %s",
1656 new_session->id, error->message);
1657 } else {
1658 g_debug ("Failed to get the x11 display of session '%s'",
1659 new_session->id);
1660 }
1661 unload_new_session (new_session);
1662 return;
1663 }
1664
1665 g_debug ("ActUserManager: Found x11 display of session '%s': %s",
1666 new_session->id, x11_display);
1667
1668 new_session->x11_display = x11_display;
1669 new_session->state++;
1670
1671 load_new_session_incrementally (new_session);
1672 }
1673
1674 #ifdef WITH_SYSTEMD
1675 static void
_get_x11_display_for_new_systemd_session(ActUserManagerNewSession * new_session)1676 _get_x11_display_for_new_systemd_session (ActUserManagerNewSession *new_session)
1677 {
1678 g_autofree gchar *session_type = NULL;
1679 g_autofree gchar *x11_display = NULL;
1680 int res;
1681
1682 res = sd_session_get_type (new_session->id,
1683 &session_type);
1684 if (res < 0) {
1685 g_debug ("ActUserManager: Failed to get the type of session '%s': %s",
1686 new_session->id,
1687 strerror (-res));
1688 unload_new_session (new_session);
1689 return;
1690 }
1691
1692 if (g_strcmp0 (session_type, "x11") != 0 &&
1693 g_strcmp0 (session_type, "wayland") != 0) {
1694 g_debug ("ActUserManager: (mostly) ignoring %s session '%s' since it's not graphical",
1695 session_type,
1696 new_session->id);
1697 x11_display = NULL;
1698 goto done;
1699 }
1700
1701 res = sd_session_get_display (new_session->id,
1702 &x11_display);
1703 if (res < 0) {
1704 g_debug ("ActUserManager: Failed to get the x11 display of session '%s': %s",
1705 new_session->id,
1706 strerror (-res));
1707 g_debug ("ActUserManager: Treating X11 display as blank");
1708 x11_display = strdup ("");
1709 } else {
1710 g_debug ("ActUserManager: Found x11 display of session '%s': %s",
1711 new_session->id, x11_display);
1712 }
1713
1714 done:
1715 new_session->x11_display = g_strdup (x11_display);
1716 new_session->state++;
1717
1718 load_new_session_incrementally (new_session);
1719 }
1720 #endif
1721
1722 static void
get_x11_display_for_new_session(ActUserManagerNewSession * new_session)1723 get_x11_display_for_new_session (ActUserManagerNewSession *new_session)
1724 {
1725 #ifdef WITH_SYSTEMD
1726 if (LOGIND_RUNNING()) {
1727 _get_x11_display_for_new_systemd_session (new_session);
1728 return;
1729 }
1730 #endif
1731
1732 g_assert (new_session->proxy != NULL);
1733
1734 new_session->pending_calls++;
1735 console_kit_session_call_get_x11_display (new_session->proxy,
1736 new_session->cancellable,
1737 on_get_x11_display_finished,
1738 new_session);
1739 }
1740
1741 static void
maybe_add_new_session(ActUserManagerNewSession * new_session)1742 maybe_add_new_session (ActUserManagerNewSession *new_session)
1743 {
1744 ActUserManager *manager;
1745 ActUser *user;
1746 gboolean is_ours;
1747
1748 manager = ACT_USER_MANAGER (new_session->manager);
1749
1750 is_ours = TRUE;
1751
1752 if (new_session->x11_display == NULL) {
1753 g_debug ("AcUserManager: (mostly) ignoring session '%s' since it's not graphical",
1754 new_session->id);
1755 is_ours = FALSE;
1756 } else if (session_is_login_window (manager, new_session->id)) {
1757 new_session->state = ACT_USER_MANAGER_NEW_SESSION_STATE_LOADED;
1758 unload_new_session (new_session);
1759 return;
1760 } else if (!session_is_on_our_seat (manager, new_session->id)) {
1761 is_ours = FALSE;
1762 }
1763
1764 user = act_user_manager_get_user_by_id (manager, new_session->uid);
1765 if (user == NULL) {
1766 unload_new_session (new_session);
1767 return;
1768 }
1769
1770 add_session_for_user (manager, user, new_session->id, is_ours);
1771 }
1772
1773 static void
load_new_session(ActUserManager * manager,const char * session_id)1774 load_new_session (ActUserManager *manager,
1775 const char *session_id)
1776 {
1777 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1778 ActUserManagerNewSession *new_session;
1779
1780 new_session = g_slice_new0 (ActUserManagerNewSession);
1781
1782 new_session->manager = g_object_ref (manager);
1783 new_session->id = g_strdup (session_id);
1784 new_session->state = ACT_USER_MANAGER_NEW_SESSION_STATE_UNLOADED + 1;
1785 new_session->cancellable = g_cancellable_new ();
1786
1787 priv->new_sessions = g_slist_prepend (priv->new_sessions, new_session);
1788 load_new_session_incrementally (new_session);
1789 }
1790
1791 static void
seat_session_added(GDBusProxy * seat_proxy,const char * session_id,ActUserManager * manager)1792 seat_session_added (GDBusProxy *seat_proxy,
1793 const char *session_id,
1794 ActUserManager *manager)
1795 {
1796 g_debug ("ActUserManager: Session added: %s", session_id);
1797
1798 load_new_session (manager, session_id);
1799 }
1800
1801 static gint
match_new_session_cmpfunc(gconstpointer a,gconstpointer b)1802 match_new_session_cmpfunc (gconstpointer a,
1803 gconstpointer b)
1804 {
1805 ActUserManagerNewSession *new_session;
1806 const char *session_id;
1807
1808 new_session = (ActUserManagerNewSession *) a;
1809 session_id = (const char *) b;
1810
1811 return strcmp (new_session->id, session_id);
1812 }
1813
1814 static void
_remove_session(ActUserManager * manager,const char * session_id)1815 _remove_session (ActUserManager *manager,
1816 const char *session_id)
1817 {
1818 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1819 ActUser *user;
1820 GSList *found;
1821
1822 g_debug ("ActUserManager: Session removed: %s", session_id);
1823
1824 found = g_slist_find_custom (priv->new_sessions,
1825 session_id,
1826 match_new_session_cmpfunc);
1827
1828 if (found != NULL) {
1829 ActUserManagerNewSession *new_session;
1830
1831 new_session = (ActUserManagerNewSession *) found->data;
1832
1833 if (new_session->state > ACT_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY) {
1834 g_debug ("ActUserManager: New session for uid %d on "
1835 "x11 display %s removed before fully loading",
1836 (int) new_session->uid, new_session->x11_display);
1837 } else if (new_session->state > ACT_USER_MANAGER_NEW_SESSION_STATE_GET_UID) {
1838 g_debug ("ActUserManager: New session for uid %d "
1839 "removed before fully loading",
1840 (int) new_session->uid);
1841 } else {
1842 g_debug ("ActUserManager: New session removed "
1843 "before fully loading");
1844 }
1845 unload_new_session (new_session);
1846 return;
1847 }
1848
1849 /* since the session object may already be gone
1850 * we can't query CK directly */
1851
1852 user = g_hash_table_lookup (priv->sessions, session_id);
1853
1854 if (user == NULL) {
1855 /* nothing to do */
1856 return;
1857 }
1858
1859 g_debug ("ActUserManager: Session removed for %s", describe_user (user));
1860 _act_user_remove_session (user, session_id);
1861 g_hash_table_remove (priv->sessions, session_id);
1862 }
1863
1864 static void
seat_session_removed(GDBusProxy * seat_proxy,const char * session_id,ActUserManager * manager)1865 seat_session_removed (GDBusProxy *seat_proxy,
1866 const char *session_id,
1867 ActUserManager *manager)
1868 {
1869 _remove_session (manager, session_id);
1870 }
1871
1872 #ifdef WITH_SYSTEMD
1873
1874 static gboolean
_session_recognized(ActUserManager * manager,const char * session_id)1875 _session_recognized (ActUserManager *manager,
1876 const char *session_id)
1877 {
1878 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1879 GSList *node;
1880
1881 if (g_hash_table_contains (priv->sessions, session_id)) {
1882 return TRUE;
1883 }
1884
1885 node = priv->new_sessions;
1886 while (node != NULL) {
1887 ActUserManagerNewSession *new_session = node->data;
1888
1889 if (g_strcmp0 (new_session->id, session_id) == 0) {
1890 return TRUE;
1891 }
1892
1893 node = node->next;
1894 }
1895 return FALSE;
1896 }
1897
1898 static void
_add_systemd_session(ActUserManager * manager,const char * session_id)1899 _add_systemd_session (ActUserManager *manager,
1900 const char *session_id)
1901 {
1902 load_new_session (manager, session_id);
1903 }
1904
1905 static void
_add_new_systemd_sessions(ActUserManager * manager,GHashTable * systemd_sessions)1906 _add_new_systemd_sessions (ActUserManager *manager,
1907 GHashTable *systemd_sessions)
1908 {
1909 GHashTableIter iter;
1910 gpointer key, value;
1911
1912 g_hash_table_iter_init (&iter, systemd_sessions);
1913 while (g_hash_table_iter_next (&iter, &key, &value)) {
1914 char *session_id = key;
1915
1916 if (!_session_recognized (manager, session_id)) {
1917 _add_systemd_session (manager, session_id);
1918 }
1919 }
1920 }
1921
1922 static void
_remove_systemd_session(ActUserManager * manager,const char * session_id)1923 _remove_systemd_session (ActUserManager *manager,
1924 const char *session_id)
1925 {
1926 _remove_session (manager, session_id);
1927 }
1928
1929 static void
_remove_stale_systemd_sessions(ActUserManager * manager,GHashTable * systemd_sessions)1930 _remove_stale_systemd_sessions (ActUserManager *manager,
1931 GHashTable *systemd_sessions)
1932 {
1933 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
1934 GHashTableIter iter;
1935 gpointer key, value;
1936 GSList *node, *sessions_to_remove;
1937
1938 sessions_to_remove = NULL;
1939 g_hash_table_iter_init (&iter, priv->sessions);
1940 while (g_hash_table_iter_next (&iter, &key, &value)) {
1941 char *session_id = key;
1942
1943 if (g_hash_table_contains (systemd_sessions, session_id)) {
1944 continue;
1945 }
1946
1947 sessions_to_remove = g_slist_prepend (sessions_to_remove, session_id);
1948 }
1949
1950 node = priv->new_sessions;
1951 while (node != NULL) {
1952 ActUserManagerNewSession *new_session = node->data;
1953 node = node->next;
1954
1955 if (g_hash_table_contains (systemd_sessions, new_session->id)) {
1956 continue;
1957 }
1958
1959 sessions_to_remove = g_slist_prepend (sessions_to_remove, new_session->id);
1960 }
1961
1962 node = sessions_to_remove;
1963 while (node != NULL) {
1964 char *session_id = node->data;
1965 GSList *next_node = node->next;
1966
1967 _remove_systemd_session (manager, session_id);
1968
1969 node = next_node;
1970 }
1971
1972 g_slist_free (sessions_to_remove);
1973 }
1974
1975 #ifdef WITH_SYSTEMD
1976 static void
reload_systemd_sessions(ActUserManager * manager)1977 reload_systemd_sessions (ActUserManager *manager)
1978 {
1979 int res;
1980 int i;
1981 g_auto(GStrv) sessions = NULL;
1982 g_autoptr(GHashTable) systemd_sessions = NULL;
1983
1984 res = sd_get_sessions (&sessions);
1985 if (res < 0) {
1986 g_debug ("Failed to determine sessions: %s", strerror (-res));
1987 return;
1988 }
1989
1990 systemd_sessions = g_hash_table_new (g_str_hash,
1991 g_str_equal);
1992
1993 if (sessions != NULL) {
1994 for (i = 0; sessions[i] != NULL; i ++) {
1995 g_autofree gchar *state = NULL;
1996 g_autofree gchar *session_class = NULL;
1997
1998 res = sd_session_get_state (sessions[i], &state);
1999 if (res < 0) {
2000 g_debug ("Failed to determine state of session %s: %s", sessions[i], strerror (-res));
2001 continue;
2002 }
2003
2004 if (g_strcmp0 (state, "closing") == 0) {
2005 continue;
2006 }
2007
2008 res = sd_session_get_class (sessions[i], &session_class);
2009 if (res < 0) {
2010 g_debug ("Failed to determine class of session %s: %s", sessions[i], strerror (-res));
2011 continue;
2012 }
2013
2014 if (g_strcmp0 (session_class, "user") != 0) {
2015 g_debug ("Ignoring non-user session %s (class %s)", sessions[i], session_class);
2016 continue;
2017 }
2018
2019 g_hash_table_insert (systemd_sessions,
2020 sessions[i], NULL);
2021 }
2022
2023 }
2024
2025 _add_new_systemd_sessions (manager, systemd_sessions);
2026 _remove_stale_systemd_sessions (manager, systemd_sessions);
2027 }
2028
2029 #endif
2030 static gboolean
on_session_monitor_event(GPollableInputStream * stream,ActUserManager * manager)2031 on_session_monitor_event (GPollableInputStream *stream,
2032 ActUserManager *manager)
2033 {
2034 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2035 sd_login_monitor_flush (priv->seat.session_monitor);
2036 reload_systemd_sessions (manager);
2037 return TRUE;
2038 }
2039
2040 static void
_monitor_for_systemd_session_changes(ActUserManager * manager)2041 _monitor_for_systemd_session_changes (ActUserManager *manager)
2042 {
2043 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2044 int res;
2045 int fd;
2046 GSource *source;
2047
2048 res = sd_login_monitor_new ("session", &priv->seat.session_monitor);
2049
2050 if (res < 0) {
2051 g_warning ("Failed to monitor logind session changes: %s",
2052 strerror (-res));
2053 unload_seat (manager);
2054 return;
2055 }
2056
2057 fd = sd_login_monitor_get_fd (priv->seat.session_monitor);
2058
2059 priv->seat.session_monitor_stream = g_unix_input_stream_new (fd, FALSE);
2060 source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (priv->seat.session_monitor_stream),
2061 NULL);
2062 g_source_set_callback (source,
2063 (GSourceFunc)
2064 on_session_monitor_event,
2065 manager,
2066 NULL);
2067 priv->seat.session_monitor_source_id = g_source_attach (source, NULL);
2068 g_source_unref (source);
2069 }
2070 #endif
2071
2072 static void
get_seat_proxy(ActUserManager * manager)2073 get_seat_proxy (ActUserManager *manager)
2074 {
2075 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2076 g_autoptr(GError) error = NULL;
2077
2078 #ifdef WITH_SYSTEMD
2079 if (LOGIND_RUNNING()) {
2080 _monitor_for_systemd_session_changes (manager);
2081 priv->seat.state++;
2082 return;
2083 }
2084 #endif
2085
2086 g_assert (priv->seat.seat_proxy == NULL);
2087
2088 priv->seat.seat_proxy = console_kit_seat_proxy_new_sync (priv->connection,
2089 G_DBUS_PROXY_FLAGS_NONE,
2090 CK_NAME,
2091 priv->seat.id,
2092 NULL,
2093 &error);
2094 if (priv->seat.seat_proxy == NULL) {
2095 if (error != NULL) {
2096 g_warning ("Failed to connect to the ConsoleKit seat object: %s",
2097 error->message);
2098 } else {
2099 g_warning ("Failed to connect to the ConsoleKit seat object");
2100 }
2101 unload_seat (manager);
2102 return;
2103 }
2104
2105 g_signal_connect (priv->seat.seat_proxy,
2106 "session-added",
2107 G_CALLBACK (seat_session_added),
2108 manager);
2109 g_signal_connect (priv->seat.seat_proxy,
2110 "session-removed",
2111 G_CALLBACK (seat_session_removed),
2112 manager);
2113 priv->seat.state++;
2114 }
2115
2116 static void
on_console_kit_session_proxy_gotten(GObject * object,GAsyncResult * result,gpointer user_data)2117 on_console_kit_session_proxy_gotten (GObject *object, GAsyncResult *result, gpointer user_data)
2118 {
2119 ActUserManager *manager = user_data;
2120 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2121 g_autoptr(GError) error = NULL;
2122
2123 g_debug ("on_console_kit_session_proxy_gotten");
2124
2125 priv->seat.session_proxy = console_kit_session_proxy_new_finish (result, &error);
2126
2127 if (priv->seat.session_proxy == NULL) {
2128 if (error != NULL) {
2129 g_warning ("Failed to connect to the ConsoleKit session object: %s",
2130 error->message);
2131 } else {
2132 g_warning ("Failed to connect to the ConsoleKit session object");
2133 }
2134 unload_seat (manager);
2135
2136 goto out;
2137 }
2138
2139 priv->seat.state++;
2140 load_seat_incrementally (manager);
2141
2142 out:
2143 g_debug ("ActUserManager: unrefing manager owned by ConsoleKit proxy getter");
2144 g_object_unref (manager);
2145 }
2146
2147 static void
get_session_proxy(ActUserManager * manager)2148 get_session_proxy (ActUserManager *manager)
2149 {
2150 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2151
2152 #ifdef WITH_SYSTEMD
2153 if (LOGIND_RUNNING()) {
2154 priv->seat.state++;
2155 queue_load_seat_incrementally (manager);
2156 return;
2157 }
2158 #endif
2159
2160 g_debug ("ActUserManager: fetching user proxy");
2161
2162 g_assert (priv->seat.session_proxy == NULL);
2163
2164 console_kit_session_proxy_new (priv->connection,
2165 G_DBUS_PROXY_FLAGS_NONE,
2166 CK_NAME,
2167 priv->seat.session_id,
2168 NULL,
2169 on_console_kit_session_proxy_gotten,
2170 g_object_ref (manager));
2171 }
2172
2173 static void
unload_seat(ActUserManager * manager)2174 unload_seat (ActUserManager *manager)
2175 {
2176 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2177
2178 priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED;
2179
2180 if (priv->seat.seat_proxy != NULL) {
2181 g_object_unref (priv->seat.seat_proxy);
2182 priv->seat.seat_proxy = NULL;
2183 }
2184
2185 if (priv->seat.session_proxy != NULL) {
2186 g_object_unref (priv->seat.session_proxy);
2187 priv->seat.session_proxy = NULL;
2188 }
2189
2190 g_free (priv->seat.id);
2191 priv->seat.id = NULL;
2192
2193 g_free (priv->seat.session_id);
2194 priv->seat.session_id = NULL;
2195
2196 g_debug ("ActUserManager: seat unloaded, so trying to set loaded property");
2197 maybe_set_is_loaded (manager);
2198 }
2199
2200 static void
load_new_session_incrementally(ActUserManagerNewSession * new_session)2201 load_new_session_incrementally (ActUserManagerNewSession *new_session)
2202 {
2203 switch (new_session->state) {
2204 case ACT_USER_MANAGER_NEW_SESSION_STATE_GET_PROXY:
2205 get_proxy_for_new_session (new_session);
2206 break;
2207 case ACT_USER_MANAGER_NEW_SESSION_STATE_GET_UID:
2208 get_uid_for_new_session (new_session);
2209 break;
2210 case ACT_USER_MANAGER_NEW_SESSION_STATE_GET_X11_DISPLAY:
2211 get_x11_display_for_new_session (new_session);
2212 break;
2213 case ACT_USER_MANAGER_NEW_SESSION_STATE_MAYBE_ADD:
2214 maybe_add_new_session (new_session);
2215 break;
2216 case ACT_USER_MANAGER_NEW_SESSION_STATE_LOADED:
2217 break;
2218 default:
2219 g_assert_not_reached ();
2220 }
2221 }
2222
2223 static void
free_fetch_user_request(ActUserManagerFetchUserRequest * request)2224 free_fetch_user_request (ActUserManagerFetchUserRequest *request)
2225 {
2226 ActUserManager *manager = request->manager;
2227 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2228
2229 g_object_set_data (G_OBJECT (request->user), "fetch-user-request", NULL);
2230
2231 priv->fetch_user_requests = g_slist_remove (priv->fetch_user_requests, request);
2232 if (request->type == ACT_USER_MANAGER_FETCH_USER_FROM_USERNAME_REQUEST) {
2233 g_free (request->username);
2234 }
2235
2236 g_free (request->object_path);
2237 g_free (request->description);
2238 g_debug ("ActUserManager: unrefing manager owned by fetch user request");
2239 g_object_unref (manager);
2240
2241 g_slice_free (ActUserManagerFetchUserRequest, request);
2242 }
2243
2244 static void
give_up(ActUserManager * manager,ActUserManagerFetchUserRequest * request)2245 give_up (ActUserManager *manager,
2246 ActUserManagerFetchUserRequest *request)
2247 {
2248 if (request->type == ACT_USER_MANAGER_FETCH_USER_FROM_USERNAME_REQUEST)
2249 g_debug ("ActUserManager: failed to load user %s", request->username);
2250 else
2251 g_debug ("ActUserManager: failed to load user %lu", (gulong) request->uid);
2252
2253 request->state = ACT_USER_MANAGER_GET_USER_STATE_UNFETCHED;
2254
2255 if (request->user)
2256 _act_user_update_as_nonexistent (request->user);
2257 }
2258
2259 static void
on_user_manager_maybe_ready_for_request(ActUserManager * manager,GParamSpec * pspec,ActUserManagerFetchUserRequest * request)2260 on_user_manager_maybe_ready_for_request (ActUserManager *manager,
2261 GParamSpec *pspec,
2262 ActUserManagerFetchUserRequest *request)
2263 {
2264 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2265
2266 if (!priv->is_loaded) {
2267 return;
2268 }
2269
2270 g_debug ("ActUserManager: user manager now loaded, proceeding with fetch user request for %s",
2271 request->description);
2272
2273 g_signal_handlers_disconnect_by_func (manager, on_user_manager_maybe_ready_for_request, request);
2274
2275 request->state++;
2276 fetch_user_incrementally (request);
2277 }
2278
2279 static void
fetch_user_incrementally(ActUserManagerFetchUserRequest * request)2280 fetch_user_incrementally (ActUserManagerFetchUserRequest *request)
2281 {
2282 ActUserManager *manager = request->manager;
2283 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2284
2285 g_debug ("ActUserManager: finding %s state %d",
2286 request->description, request->state);
2287 switch (request->state) {
2288 case ACT_USER_MANAGER_GET_USER_STATE_WAIT_FOR_LOADED:
2289 if (priv->is_loaded) {
2290 request->state++;
2291 fetch_user_incrementally (request);
2292 } else {
2293 g_debug ("ActUserManager: waiting for user manager to load before finding %s",
2294 request->description);
2295 g_signal_connect (manager, "notify::is-loaded",
2296 G_CALLBACK (on_user_manager_maybe_ready_for_request), request);
2297
2298 }
2299 break;
2300
2301 case ACT_USER_MANAGER_GET_USER_STATE_ASK_ACCOUNTS_SERVICE:
2302 if (priv->accounts_proxy == NULL) {
2303 give_up (manager, request);
2304 } else {
2305 find_user_in_accounts_service (manager, request);
2306 }
2307 break;
2308 case ACT_USER_MANAGER_GET_USER_STATE_FETCHED:
2309 g_debug ("ActUserManager: %s fetched", request->description);
2310 _act_user_update_from_object_path (request->user, request->object_path);
2311 break;
2312 case ACT_USER_MANAGER_GET_USER_STATE_UNFETCHED:
2313 g_debug ("ActUserManager: %s was not fetched", request->description);
2314 break;
2315 default:
2316 g_assert_not_reached ();
2317 }
2318
2319 if (request->state == ACT_USER_MANAGER_GET_USER_STATE_FETCHED ||
2320 request->state == ACT_USER_MANAGER_GET_USER_STATE_UNFETCHED) {
2321 g_debug ("ActUserManager: finished handling request for %s",
2322 request->description);
2323 free_fetch_user_request (request);
2324 }
2325 }
2326
2327 static void
fetch_user_with_username_from_accounts_service(ActUserManager * manager,ActUser * user,const char * username)2328 fetch_user_with_username_from_accounts_service (ActUserManager *manager,
2329 ActUser *user,
2330 const char *username)
2331 {
2332 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2333 ActUserManagerFetchUserRequest *request;
2334
2335 request = g_slice_new0 (ActUserManagerFetchUserRequest);
2336
2337 request->manager = g_object_ref (manager);
2338 request->type = ACT_USER_MANAGER_FETCH_USER_FROM_USERNAME_REQUEST;
2339 request->username = g_strdup (username);
2340 request->user = user;
2341 request->state = ACT_USER_MANAGER_GET_USER_STATE_UNFETCHED + 1;
2342 request->description = g_strdup_printf ("user '%s'", request->username);
2343
2344 priv->fetch_user_requests = g_slist_prepend (priv->fetch_user_requests,
2345 request);
2346 g_object_set_data (G_OBJECT (user), "fetch-user-request", request);
2347 fetch_user_incrementally (request);
2348 }
2349
2350 static void
fetch_user_with_id_from_accounts_service(ActUserManager * manager,ActUser * user,uid_t id)2351 fetch_user_with_id_from_accounts_service (ActUserManager *manager,
2352 ActUser *user,
2353 uid_t id)
2354 {
2355 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2356 ActUserManagerFetchUserRequest *request;
2357
2358 request = g_slice_new0 (ActUserManagerFetchUserRequest);
2359
2360 request->manager = g_object_ref (manager);
2361 request->type = ACT_USER_MANAGER_FETCH_USER_FROM_ID_REQUEST;
2362 request->uid = id;
2363 request->user = user;
2364 request->state = ACT_USER_MANAGER_GET_USER_STATE_UNFETCHED + 1;
2365 request->description = g_strdup_printf ("user with id %lu", (gulong) request->uid);
2366
2367 priv->fetch_user_requests = g_slist_prepend (priv->fetch_user_requests,
2368 request);
2369 g_object_set_data (G_OBJECT (user), "fetch-user-request", request);
2370 fetch_user_incrementally (request);
2371 }
2372
2373 /**
2374 * act_user_manager_get_user:
2375 * @manager: the manager to query.
2376 * @username: the login name of the user to get.
2377 *
2378 * Retrieves a pointer to the #ActUser object for the login @username
2379 * from @manager. Trying to use this object before its
2380 * #ActUser:is-loaded property is %TRUE will result in undefined
2381 * behavior.
2382 *
2383 * Returns: (transfer none): #ActUser object
2384 **/
2385 ActUser *
act_user_manager_get_user(ActUserManager * manager,const char * username)2386 act_user_manager_get_user (ActUserManager *manager,
2387 const char *username)
2388 {
2389 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2390 ActUser *user;
2391
2392 g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), NULL);
2393 g_return_val_if_fail (username != NULL && username[0] != '\0', NULL);
2394
2395 user = lookup_user_by_name (manager, username);
2396
2397 /* if we don't have it loaded try to load it now */
2398 if (user == NULL) {
2399 g_debug ("ActUserManager: trying to track new user with username %s", username);
2400 user = create_new_user (manager);
2401
2402 if (priv->accounts_proxy != NULL) {
2403 fetch_user_with_username_from_accounts_service (manager, user, username);
2404 }
2405 }
2406
2407 return user;
2408 }
2409
2410 static void
load_user(ActUserManager * manager,const char * username)2411 load_user (ActUserManager *manager,
2412 const char *username)
2413 {
2414 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2415 ActUser *user;
2416 g_autoptr(GError) error = NULL;
2417 char *object_path = NULL;
2418 gboolean user_found;
2419
2420 g_return_if_fail (ACT_IS_USER_MANAGER (manager));
2421 g_return_if_fail (username != NULL && username[0] != '\0');
2422
2423 user = lookup_user_by_name (manager, username);
2424
2425 if (user == NULL) {
2426 g_debug ("ActUserManager: trying to track new user with username %s", username);
2427 user = create_new_user (manager);
2428 }
2429
2430 user_found = accounts_accounts_call_find_user_by_name_sync (priv->accounts_proxy,
2431 username,
2432 &object_path,
2433 NULL,
2434 &error);
2435
2436 if (!user_found) {
2437 if (error != NULL) {
2438 g_debug ("ActUserManager: Failed to find user '%s': %s",
2439 username, error->message);
2440 } else {
2441 g_debug ("ActUserManager: Failed to find user '%s'",
2442 username);
2443 }
2444 }
2445
2446 _act_user_update_from_object_path (user, object_path);
2447 }
2448
2449 /**
2450 * act_user_manager_get_user_by_id:
2451 * @manager: the manager to query.
2452 * @id: the uid of the user to get.
2453 *
2454 * Retrieves a pointer to the #ActUser object for the user with the
2455 * given uid from @manager. Trying to use this object before its
2456 * #ActUser:is-loaded property is %TRUE will result in undefined
2457 * behavior.
2458 *
2459 * Returns: (transfer none): #ActUser object
2460 */
2461 ActUser *
act_user_manager_get_user_by_id(ActUserManager * manager,uid_t id)2462 act_user_manager_get_user_by_id (ActUserManager *manager,
2463 uid_t id)
2464 {
2465 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2466 ActUser *user;
2467 g_autofree gchar *object_path = NULL;
2468
2469 g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), NULL);
2470
2471 object_path = g_strdup_printf ("/org/freedesktop/Accounts/User%lu", (gulong) id);
2472 user = g_hash_table_lookup (priv->users_by_object_path, object_path);
2473
2474 if (user != NULL) {
2475 return g_object_ref (user);
2476 } else {
2477 g_debug ("ActUserManager: trying to track new user with uid %lu", (gulong) id);
2478 user = create_new_user (manager);
2479
2480 if (priv->accounts_proxy != NULL) {
2481 fetch_user_with_id_from_accounts_service (manager, user, id);
2482 }
2483 }
2484
2485 return user;
2486 }
2487
2488 static void
listify_hash_values_hfunc(gpointer key,gpointer value,gpointer user_data)2489 listify_hash_values_hfunc (gpointer key,
2490 gpointer value,
2491 gpointer user_data)
2492 {
2493 GSList **list = user_data;
2494
2495 *list = g_slist_prepend (*list, value);
2496 }
2497
2498 /**
2499 * act_user_manager_list_users:
2500 * @manager: a #ActUserManager
2501 *
2502 * Get a list of system user accounts
2503 *
2504 * Returns: (element-type ActUser) (transfer container): List of #ActUser objects
2505 */
2506 GSList *
act_user_manager_list_users(ActUserManager * manager)2507 act_user_manager_list_users (ActUserManager *manager)
2508 {
2509 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2510 GSList *retval;
2511
2512 g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), NULL);
2513
2514 if (!priv->list_cached_users_done) {
2515 load_users (manager);
2516
2517 if (priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_GET_SEAT_PROXY)
2518 queue_load_seat_incrementally (manager);
2519 }
2520
2521 retval = NULL;
2522 g_hash_table_foreach (priv->normal_users_by_name, listify_hash_values_hfunc, &retval);
2523
2524 return g_slist_sort (retval, (GCompareFunc) act_user_collate);
2525 }
2526
2527 static void
maybe_set_is_loaded(ActUserManager * manager)2528 maybe_set_is_loaded (ActUserManager *manager)
2529 {
2530 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2531
2532 if (priv->is_loaded) {
2533 g_debug ("ActUserManager: already loaded, so not setting loaded property");
2534 return;
2535 }
2536
2537 if (priv->getting_sessions) {
2538 g_debug ("ActUserManager: GetSessions call pending, so not setting loaded property");
2539 return;
2540 }
2541
2542 if (priv->new_users_inhibiting_load != NULL) {
2543 g_debug ("ActUserManager: Loading new users, so not setting loaded property");
2544 return;
2545 }
2546
2547 /* Don't set is_loaded yet unless the seat is already loaded enough
2548 * or failed to load.
2549 */
2550 if (priv->seat.state >= ACT_USER_MANAGER_SEAT_STATE_GET_ID) {
2551 g_debug ("ActUserManager: Seat loaded, so now setting loaded property");
2552 } else if (priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_UNLOADED) {
2553 g_debug ("ActUserManager: Seat wouldn't load, so giving up on it and setting loaded property");
2554 } else {
2555 g_debug ("ActUserManager: Seat still actively loading, so not setting loaded property");
2556 return;
2557 }
2558
2559 set_is_loaded (manager, TRUE);
2560 }
2561
2562
2563 static GSList *
slist_deep_copy(const GSList * list)2564 slist_deep_copy (const GSList *list)
2565 {
2566 GSList *retval;
2567 GSList *l;
2568
2569 if (list == NULL)
2570 return NULL;
2571
2572 retval = g_slist_copy ((GSList *) list);
2573 for (l = retval; l != NULL; l = l->next) {
2574 l->data = g_strdup (l->data);
2575 }
2576
2577 return retval;
2578 }
2579
2580 static void
on_get_sessions_finished(GObject * object,GAsyncResult * result,gpointer data)2581 on_get_sessions_finished (GObject *object,
2582 GAsyncResult *result,
2583 gpointer data)
2584 {
2585 ConsoleKitSeat *proxy = CONSOLE_KIT_SEAT (object);
2586 g_autoptr(ActUserManager) manager = data;
2587 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2588 g_autoptr(GError) error = NULL;
2589 g_auto(GStrv) session_ids = NULL;
2590 int i;
2591
2592 if (!console_kit_seat_call_get_sessions_finish (proxy, &session_ids, result, &error)) {
2593 if (error != NULL) {
2594 g_warning ("unable to determine sessions for seat: %s",
2595 error->message);
2596 } else {
2597 g_warning ("unable to determine sessions for seat");
2598 }
2599
2600 return;
2601 }
2602
2603 priv->getting_sessions = FALSE;
2604 for (i = 0; session_ids[i] != NULL; i++) {
2605 load_new_session (manager, session_ids[i]);
2606 }
2607
2608 g_debug ("ActUserManager: GetSessions call finished, so trying to set loaded property");
2609 maybe_set_is_loaded (manager);
2610 }
2611
2612 static void
load_console_kit_sessions(ActUserManager * manager)2613 load_console_kit_sessions (ActUserManager *manager)
2614 {
2615 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2616
2617 if (priv->seat.seat_proxy == NULL) {
2618 g_debug ("ActUserManager: no seat proxy; can't load sessions");
2619 return;
2620 }
2621
2622 priv->getting_sessions = TRUE;
2623 console_kit_seat_call_get_sessions (priv->seat.seat_proxy,
2624 NULL,
2625 on_get_sessions_finished,
2626 g_object_ref (manager));
2627 }
2628
2629 static void
load_sessions(ActUserManager * manager)2630 load_sessions (ActUserManager *manager)
2631 {
2632 #ifdef WITH_SYSTEMD
2633 if (LOGIND_RUNNING()) {
2634 reload_systemd_sessions (manager);
2635 maybe_set_is_loaded (manager);
2636 return;
2637 }
2638 #endif
2639 load_console_kit_sessions (manager);
2640 }
2641
2642 static void
load_users(ActUserManager * manager)2643 load_users (ActUserManager *manager)
2644 {
2645 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2646 g_autoptr(GError) error = NULL;
2647 g_auto(GStrv) user_paths = NULL;
2648 gboolean could_list = FALSE;
2649
2650 if (!ensure_accounts_proxy (manager)) {
2651 return;
2652 }
2653
2654 g_debug ("ActUserManager: calling 'ListCachedUsers'");
2655
2656 could_list = accounts_accounts_call_list_cached_users_sync (priv->accounts_proxy,
2657 &user_paths,
2658 NULL, &error);
2659
2660 if (!could_list) {
2661 g_debug ("ActUserManager: ListCachedUsers failed: %s", error->message);
2662 return;
2663 }
2664
2665 load_user_paths (manager, (const char * const *) user_paths);
2666
2667 load_included_usernames (manager);
2668
2669 priv->list_cached_users_done = TRUE;
2670 }
2671
2672 static gboolean
load_seat_incrementally(ActUserManager * manager)2673 load_seat_incrementally (ActUserManager *manager)
2674 {
2675 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2676
2677 priv->seat.load_idle_id = 0;
2678
2679 switch (priv->seat.state) {
2680 case ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_ID:
2681 get_current_session_id (manager);
2682 break;
2683 case ACT_USER_MANAGER_SEAT_STATE_GET_SESSION_PROXY:
2684 get_session_proxy (manager);
2685 break;
2686 case ACT_USER_MANAGER_SEAT_STATE_GET_ID:
2687 get_seat_id_for_current_session (manager);
2688 break;
2689 case ACT_USER_MANAGER_SEAT_STATE_GET_SEAT_PROXY:
2690 get_seat_proxy (manager);
2691 break;
2692 case ACT_USER_MANAGER_SEAT_STATE_LOADED:
2693 g_debug ("ActUserManager: Seat loading sequence complete");
2694 break;
2695 default:
2696 g_assert_not_reached ();
2697 }
2698
2699 if (priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_LOADED) {
2700 load_sessions (manager);
2701 }
2702
2703 maybe_set_is_loaded (manager);
2704
2705 return FALSE;
2706 }
2707
2708 static gboolean
load_idle(ActUserManager * manager)2709 load_idle (ActUserManager *manager)
2710 {
2711 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2712
2713 priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED + 1;
2714 load_seat_incrementally (manager);
2715 priv->load_id = 0;
2716
2717 return FALSE;
2718 }
2719
2720 static void
queue_load_seat(ActUserManager * manager)2721 queue_load_seat (ActUserManager *manager)
2722 {
2723 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2724
2725 if (priv->load_id > 0) {
2726 return;
2727 }
2728
2729 priv->load_id = g_idle_add ((GSourceFunc)load_idle, manager);
2730 }
2731
2732 static void
act_user_manager_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)2733 act_user_manager_get_property (GObject *object,
2734 guint prop_id,
2735 GValue *value,
2736 GParamSpec *pspec)
2737 {
2738 ActUserManager *manager = ACT_USER_MANAGER (object);
2739 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2740
2741 switch (prop_id) {
2742 case PROP_IS_LOADED:
2743 g_value_set_boolean (value, priv->is_loaded);
2744 break;
2745 case PROP_HAS_MULTIPLE_USERS:
2746 g_value_set_boolean (value, priv->has_multiple_users);
2747 break;
2748 case PROP_INCLUDE_USERNAMES_LIST:
2749 g_value_set_pointer (value, priv->include_usernames);
2750 break;
2751 case PROP_EXCLUDE_USERNAMES_LIST:
2752 g_value_set_pointer (value, priv->exclude_usernames);
2753 break;
2754 default:
2755 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2756 break;
2757 }
2758 }
2759
2760 static void
set_include_usernames(ActUserManager * manager,GSList * list)2761 set_include_usernames (ActUserManager *manager,
2762 GSList *list)
2763 {
2764 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2765
2766 if (priv->include_usernames != NULL) {
2767 g_slist_foreach (priv->include_usernames, (GFunc) g_free, NULL);
2768 g_slist_free (priv->include_usernames);
2769 }
2770 priv->include_usernames = slist_deep_copy (list);
2771 }
2772
2773 static void
set_exclude_usernames(ActUserManager * manager,GSList * list)2774 set_exclude_usernames (ActUserManager *manager,
2775 GSList *list)
2776 {
2777 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2778
2779 if (priv->exclude_usernames != NULL) {
2780 g_slist_foreach (priv->exclude_usernames, (GFunc) g_free, NULL);
2781 g_slist_free (priv->exclude_usernames);
2782 }
2783 priv->exclude_usernames = slist_deep_copy (list);
2784 }
2785
2786 static void
act_user_manager_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)2787 act_user_manager_set_property (GObject *object,
2788 guint prop_id,
2789 const GValue *value,
2790 GParamSpec *pspec)
2791 {
2792 ActUserManager *self;
2793
2794 self = ACT_USER_MANAGER (object);
2795
2796 switch (prop_id) {
2797 case PROP_INCLUDE_USERNAMES_LIST:
2798 set_include_usernames (self, g_value_get_pointer (value));
2799 break;
2800 case PROP_EXCLUDE_USERNAMES_LIST:
2801 set_exclude_usernames (self, g_value_get_pointer (value));
2802 break;
2803 case PROP_HAS_MULTIPLE_USERS:
2804 set_has_multiple_users (self, g_value_get_boolean (value));
2805 break;
2806 default:
2807 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2808 break;
2809 }
2810 }
2811
2812 static void
act_user_manager_class_init(ActUserManagerClass * klass)2813 act_user_manager_class_init (ActUserManagerClass *klass)
2814 {
2815 GObjectClass *object_class = G_OBJECT_CLASS (klass);
2816
2817 object_class->finalize = act_user_manager_finalize;
2818 object_class->get_property = act_user_manager_get_property;
2819 object_class->set_property = act_user_manager_set_property;
2820
2821 g_object_class_install_property (object_class,
2822 PROP_IS_LOADED,
2823 g_param_spec_boolean ("is-loaded",
2824 "Is loaded",
2825 "Determines whether or not the manager object is loaded and ready to read from.",
2826 FALSE,
2827 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
2828 g_object_class_install_property (object_class,
2829 PROP_HAS_MULTIPLE_USERS,
2830 g_param_spec_boolean ("has-multiple-users",
2831 "Has multiple users",
2832 "Whether more than one normal user is present",
2833 FALSE,
2834 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2835 g_object_class_install_property (object_class,
2836 PROP_INCLUDE_USERNAMES_LIST,
2837 g_param_spec_pointer ("include-usernames-list",
2838 "Include usernames list",
2839 "Usernames who are specifically included",
2840 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2841
2842 g_object_class_install_property (object_class,
2843 PROP_EXCLUDE_USERNAMES_LIST,
2844 g_param_spec_pointer ("exclude-usernames-list",
2845 "Exclude usernames list",
2846 "Usernames who are specifically excluded",
2847 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2848
2849 /**
2850 * ActUserManager::user-added:
2851 * @gobject: the object which received the signal
2852 * @user: the #ActUser that was added
2853 *
2854 * Emitted when a user is added to the user manager.
2855 */
2856 signals [USER_ADDED] =
2857 g_signal_new ("user-added",
2858 G_TYPE_FROM_CLASS (klass),
2859 G_SIGNAL_RUN_LAST,
2860 G_STRUCT_OFFSET (ActUserManagerClass, user_added),
2861 NULL, NULL,
2862 g_cclosure_marshal_VOID__OBJECT,
2863 G_TYPE_NONE, 1, ACT_TYPE_USER);
2864 /**
2865 * ActUserManager::user-removed:
2866 * @gobject: the object which received the signal
2867 * @user: the #ActUser that was removed
2868 *
2869 * Emitted when a user is removed from the user manager.
2870 */
2871 signals [USER_REMOVED] =
2872 g_signal_new ("user-removed",
2873 G_TYPE_FROM_CLASS (klass),
2874 G_SIGNAL_RUN_LAST,
2875 G_STRUCT_OFFSET (ActUserManagerClass, user_removed),
2876 NULL, NULL,
2877 g_cclosure_marshal_VOID__OBJECT,
2878 G_TYPE_NONE, 1, ACT_TYPE_USER);
2879 /**
2880 * ActUserManager::user-is-logged-in-changed:
2881 * @gobject: the object which received the signal
2882 * @user: the #ActUser that changed login status
2883 *
2884 * One of the users has logged in or out.
2885 */
2886 signals [USER_IS_LOGGED_IN_CHANGED] =
2887 g_signal_new ("user-is-logged-in-changed",
2888 G_TYPE_FROM_CLASS (klass),
2889 G_SIGNAL_RUN_LAST,
2890 G_STRUCT_OFFSET (ActUserManagerClass, user_is_logged_in_changed),
2891 NULL, NULL,
2892 g_cclosure_marshal_VOID__OBJECT,
2893 G_TYPE_NONE, 1, ACT_TYPE_USER);
2894 /**
2895 * ActUserManager::user-changed:
2896 * @gobject: the object which received the signal
2897 * @user: the #ActUser that changed
2898 *
2899 * One of the users has changed
2900 */
2901 signals [USER_CHANGED] =
2902 g_signal_new ("user-changed",
2903 G_TYPE_FROM_CLASS (klass),
2904 G_SIGNAL_RUN_LAST,
2905 G_STRUCT_OFFSET (ActUserManagerClass, user_changed),
2906 NULL, NULL,
2907 g_cclosure_marshal_VOID__OBJECT,
2908 G_TYPE_NONE, 1, ACT_TYPE_USER);
2909 }
2910
2911 /**
2912 * act_user_manager_queue_load:
2913 * @manager: a #ActUserManager
2914 *
2915 * Queue loading users into user manager. This must be called, and the
2916 * #ActUserManager:is-loaded property must be %TRUE before calling
2917 * act_user_manager_list_users()
2918 */
2919 static void
act_user_manager_queue_load(ActUserManager * manager)2920 act_user_manager_queue_load (ActUserManager *manager)
2921 {
2922 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2923
2924 g_return_if_fail (ACT_IS_USER_MANAGER (manager));
2925
2926 if (!priv->is_loaded) {
2927 queue_load_seat (manager);
2928 }
2929 }
2930
2931 static gboolean
ensure_accounts_proxy(ActUserManager * manager)2932 ensure_accounts_proxy (ActUserManager *manager)
2933 {
2934 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2935 g_autoptr(GError) error = NULL;
2936
2937 if (priv->accounts_proxy != NULL) {
2938 return TRUE;
2939 }
2940
2941 priv->accounts_proxy = accounts_accounts_proxy_new_sync (priv->connection,
2942 G_DBUS_PROXY_FLAGS_NONE,
2943 ACCOUNTS_NAME,
2944 ACCOUNTS_PATH,
2945 NULL,
2946 &error);
2947 if (error != NULL) {
2948 g_debug ("ActUserManager: getting account proxy failed: %s", error->message);
2949 return FALSE;
2950 }
2951
2952 g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (priv->accounts_proxy), G_MAXINT);
2953
2954 g_object_bind_property (G_OBJECT (priv->accounts_proxy),
2955 "has-multiple-users",
2956 G_OBJECT (manager),
2957 "has-multiple-users",
2958 G_BINDING_SYNC_CREATE);
2959
2960 g_signal_connect (priv->accounts_proxy,
2961 "user-added",
2962 G_CALLBACK (on_new_user_in_accounts_service),
2963 manager);
2964 g_signal_connect (priv->accounts_proxy,
2965 "user-deleted",
2966 G_CALLBACK (on_user_removed_in_accounts_service),
2967 manager);
2968
2969 return TRUE;
2970 }
2971
2972 static void
act_user_manager_init(ActUserManager * manager)2973 act_user_manager_init (ActUserManager *manager)
2974 {
2975 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
2976 g_autoptr(GError) error = NULL;
2977
2978 act_user_manager_error_quark (); /* register dbus errors */
2979
2980 /* sessions */
2981 priv->sessions = g_hash_table_new_full (g_str_hash,
2982 g_str_equal,
2983 g_free,
2984 g_object_unref);
2985
2986 /* users */
2987 priv->normal_users_by_name = g_hash_table_new_full (g_str_hash,
2988 g_str_equal,
2989 g_free,
2990 g_object_unref);
2991 priv->system_users_by_name = g_hash_table_new_full (g_str_hash,
2992 g_str_equal,
2993 g_free,
2994 g_object_unref);
2995 priv->users_by_object_path = g_hash_table_new_full (g_str_hash,
2996 g_str_equal,
2997 NULL,
2998 g_object_unref);
2999
3000 priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
3001 if (priv->connection == NULL) {
3002 if (error != NULL) {
3003 g_warning ("Failed to connect to the D-Bus daemon: %s", error->message);
3004 } else {
3005 g_warning ("Failed to connect to the D-Bus daemon");
3006 }
3007 return;
3008 }
3009
3010 ensure_accounts_proxy (manager);
3011
3012 priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED;
3013 }
3014
3015 static void
act_user_manager_finalize(GObject * object)3016 act_user_manager_finalize (GObject *object)
3017 {
3018 ActUserManager *manager = ACT_USER_MANAGER (object);
3019 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3020 GSList *node;
3021
3022 g_debug ("ActUserManager: finalizing user manager");
3023
3024 g_slist_foreach (priv->new_sessions,
3025 (GFunc) unload_new_session, NULL);
3026 g_slist_free (priv->new_sessions);
3027
3028 g_slist_foreach (priv->fetch_user_requests,
3029 (GFunc) free_fetch_user_request, NULL);
3030 g_slist_free (priv->fetch_user_requests);
3031
3032 g_slist_free (priv->new_users_inhibiting_load);
3033
3034 node = priv->new_users;
3035 while (node != NULL) {
3036 ActUser *user;
3037 GSList *next_node;
3038
3039 user = ACT_USER (node->data);
3040 next_node = node->next;
3041
3042 g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
3043 g_object_unref (user);
3044 priv->new_users = g_slist_delete_link (priv->new_users, node);
3045 node = next_node;
3046 }
3047
3048 unload_seat (manager);
3049
3050 if (priv->exclude_usernames != NULL) {
3051 g_slist_foreach (priv->exclude_usernames, (GFunc) g_free, NULL);
3052 g_slist_free (priv->exclude_usernames);
3053 }
3054
3055 if (priv->include_usernames != NULL) {
3056 g_slist_foreach (priv->include_usernames, (GFunc) g_free, NULL);
3057 g_slist_free (priv->include_usernames);
3058 }
3059
3060 if (priv->seat.seat_proxy != NULL) {
3061 g_object_unref (priv->seat.seat_proxy);
3062 }
3063
3064 if (priv->seat.session_proxy != NULL) {
3065 g_object_unref (priv->seat.session_proxy);
3066 }
3067
3068 if (priv->seat.load_idle_id != 0) {
3069 g_source_remove (priv->seat.load_idle_id);
3070 }
3071
3072 #ifdef WITH_SYSTEMD
3073 if (priv->seat.session_monitor != NULL) {
3074 sd_login_monitor_unref (priv->seat.session_monitor);
3075 }
3076
3077 if (priv->seat.session_monitor_stream != NULL) {
3078 g_object_unref (priv->seat.session_monitor_stream);
3079 }
3080
3081 if (priv->seat.session_monitor_source_id != 0) {
3082 g_source_remove (priv->seat.session_monitor_source_id);
3083 }
3084 #endif
3085
3086 if (priv->accounts_proxy != NULL) {
3087 g_object_unref (priv->accounts_proxy);
3088 }
3089
3090 if (priv->load_id > 0) {
3091 g_source_remove (priv->load_id);
3092 priv->load_id = 0;
3093 }
3094
3095 g_hash_table_destroy (priv->sessions);
3096
3097 g_hash_table_destroy (priv->normal_users_by_name);
3098 g_hash_table_destroy (priv->system_users_by_name);
3099 g_hash_table_destroy (priv->users_by_object_path);
3100
3101 G_OBJECT_CLASS (act_user_manager_parent_class)->finalize (object);
3102 }
3103
3104 /**
3105 * act_user_manager_get_default:
3106 *
3107 * Returns the user manager singleton instance. Calling this function will
3108 * automatically being loading the user list if it isn't loaded already.
3109 * The #ActUserManager:is-loaded property will be set to %TRUE when the users
3110 * are finished loading and then act_user_manager_list_users() can be called.
3111 *
3112 * Returns: (transfer none): user manager object
3113 */
3114 ActUserManager *
act_user_manager_get_default(void)3115 act_user_manager_get_default (void)
3116 {
3117 if (user_manager_object == NULL) {
3118 user_manager_object = g_object_new (ACT_TYPE_USER_MANAGER, NULL);
3119 g_object_add_weak_pointer (user_manager_object,
3120 (gpointer *) &user_manager_object);
3121 act_user_manager_queue_load (user_manager_object);
3122 }
3123
3124 return ACT_USER_MANAGER (user_manager_object);
3125 }
3126
3127 /**
3128 * act_user_manager_no_service:
3129 * @manager: a #ActUserManager
3130 *
3131 * Check whether or not the accounts service is running.
3132 *
3133 * Returns: whether or not accounts service is running
3134 */
3135 gboolean
act_user_manager_no_service(ActUserManager * manager)3136 act_user_manager_no_service (ActUserManager *manager)
3137 {
3138 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3139 return priv->accounts_proxy == NULL;
3140 }
3141
3142 /**
3143 * act_user_manager_create_user:
3144 * @manager: a #ActUserManager
3145 * @username: a unix user name
3146 * @fullname: a unix GECOS value
3147 * @accounttype: a #ActUserAccountType
3148 * @error: a #GError
3149 *
3150 * Creates a user account on the system.
3151 *
3152 * Returns: (transfer full): user object
3153 */
3154 ActUser *
act_user_manager_create_user(ActUserManager * manager,const char * username,const char * fullname,ActUserAccountType accounttype,GError ** error)3155 act_user_manager_create_user (ActUserManager *manager,
3156 const char *username,
3157 const char *fullname,
3158 ActUserAccountType accounttype,
3159 GError **error)
3160 {
3161 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3162 GError *local_error = NULL;
3163 gboolean res;
3164 g_autofree gchar *path = NULL;
3165 ActUser *user;
3166
3167 g_debug ("ActUserManager: Creating user '%s', '%s', %d",
3168 username, fullname, accounttype);
3169
3170 g_assert (priv->accounts_proxy != NULL);
3171
3172 res = accounts_accounts_call_create_user_sync (priv->accounts_proxy,
3173 username,
3174 fullname,
3175 accounttype,
3176 &path,
3177 NULL,
3178 &local_error);
3179 if (!res) {
3180 g_propagate_error (error, local_error);
3181 return NULL;
3182 }
3183
3184 user = add_new_user_for_object_path (path, manager);
3185
3186 return user;
3187 }
3188
3189 static void
act_user_manager_async_complete_handler(GObject * source,GAsyncResult * result,gpointer user_data)3190 act_user_manager_async_complete_handler (GObject *source,
3191 GAsyncResult *result,
3192 gpointer user_data)
3193 {
3194 GTask *task = user_data;
3195
3196 g_task_return_pointer (task, g_object_ref (result), g_object_unref);
3197 g_object_unref (task);
3198 }
3199
3200 /**
3201 * act_user_manager_create_user_async:
3202 * @manager: a #ActUserManager
3203 * @username: a unix user name
3204 * @fullname: a unix GECOS value
3205 * @accounttype: a #ActUserAccountType
3206 * @cancellable: (allow-none): optional #GCancellable object,
3207 * %NULL to ignore
3208 * @callback: (scope async): a #GAsyncReadyCallback to call
3209 * when the request is satisfied
3210 * @user_data: (closure): the data to pass to @callback
3211 *
3212 * Asynchronously creates a user account on the system.
3213 *
3214 * For more details, see act_user_manager_create_user(), which
3215 * is the synchronous version of this call.
3216 *
3217 * Since: 0.6.27
3218 */
3219 void
act_user_manager_create_user_async(ActUserManager * manager,const char * username,const char * fullname,ActUserAccountType accounttype,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)3220 act_user_manager_create_user_async (ActUserManager *manager,
3221 const char *username,
3222 const char *fullname,
3223 ActUserAccountType accounttype,
3224 GCancellable *cancellable,
3225 GAsyncReadyCallback callback,
3226 gpointer user_data)
3227 {
3228 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3229 GTask *task;
3230
3231 g_return_if_fail (ACT_IS_USER_MANAGER (manager));
3232 g_return_if_fail (priv->accounts_proxy != NULL);
3233
3234 g_debug ("ActUserManager: Creating user (async) '%s', '%s', %d",
3235 username, fullname, accounttype);
3236
3237 g_assert (priv->accounts_proxy != NULL);
3238
3239 task = g_task_new (G_OBJECT (manager),
3240 cancellable,
3241 callback, user_data);
3242
3243 accounts_accounts_call_create_user (priv->accounts_proxy,
3244 username,
3245 fullname,
3246 accounttype,
3247 cancellable,
3248 act_user_manager_async_complete_handler, task);
3249 }
3250
3251 /**
3252 * act_user_manager_create_user_finish:
3253 * @manager: a #ActUserManager
3254 * @result: a #GAsyncResult
3255 * @error: a #GError
3256 *
3257 * Finishes an asynchronous user creation.
3258 *
3259 * See act_user_manager_create_user_async().
3260 *
3261 * Returns: (transfer full): user object
3262 *
3263 * Since: 0.6.27
3264 */
3265 ActUser *
act_user_manager_create_user_finish(ActUserManager * manager,GAsyncResult * result,GError ** error)3266 act_user_manager_create_user_finish (ActUserManager *manager,
3267 GAsyncResult *result,
3268 GError **error)
3269 {
3270 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3271 GAsyncResult *inner_result;
3272 ActUser *user = NULL;
3273 g_autofree gchar *path = NULL;
3274 GError *remote_error = NULL;
3275
3276 inner_result = g_task_propagate_pointer (G_TASK (result), error);
3277 if (inner_result == NULL) {
3278 return FALSE;
3279 }
3280
3281 if (accounts_accounts_call_create_user_finish (priv->accounts_proxy,
3282 &path, inner_result, &remote_error)) {
3283 user = add_new_user_for_object_path (path, manager);
3284 }
3285
3286 if (remote_error) {
3287 g_dbus_error_strip_remote_error (remote_error);
3288 g_propagate_error (error, remote_error);
3289 }
3290
3291 return user;
3292 }
3293
3294 /**
3295 * act_user_manager_cache_user:
3296 * @manager: a #ActUserManager
3297 * @username: a user name
3298 * @error: a #GError
3299 *
3300 * Caches a user account so it shows up via act_user_manager_list_users().
3301 *
3302 * Returns: (transfer full): user object
3303 */
3304 ActUser *
act_user_manager_cache_user(ActUserManager * manager,const char * username,GError ** error)3305 act_user_manager_cache_user (ActUserManager *manager,
3306 const char *username,
3307 GError **error)
3308 {
3309 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3310 GError *local_error = NULL;
3311 gboolean res;
3312 g_autofree gchar *path = NULL;
3313
3314 g_debug ("ActUserManager: Caching user '%s'",
3315 username);
3316
3317 g_assert (priv->accounts_proxy != NULL);
3318
3319 res = accounts_accounts_call_cache_user_sync (priv->accounts_proxy,
3320 username,
3321 &path,
3322 NULL,
3323 &local_error);
3324 if (!res) {
3325 g_propagate_error (error, local_error);
3326 return NULL;
3327 }
3328
3329 return add_new_user_for_object_path (path, manager);
3330 }
3331
3332
3333 /**
3334 * act_user_manager_cache_user_async:
3335 * @manager: a #ActUserManager
3336 * @username: a unix user name
3337 * @cancellable: (allow-none): optional #GCancellable object,
3338 * %NULL to ignore
3339 * @callback: (scope async): a #GAsyncReadyCallback to call
3340 * when the request is satisfied
3341 * @user_data: (closure): the data to pass to @callback
3342 *
3343 * Asynchronously caches a user account so it shows up via
3344 * act_user_manager_list_users().
3345 *
3346 * For more details, see act_user_manager_cache_user(), which
3347 * is the synchronous version of this call.
3348 *
3349 * Since: 0.6.27
3350 */
3351 void
act_user_manager_cache_user_async(ActUserManager * manager,const char * username,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)3352 act_user_manager_cache_user_async (ActUserManager *manager,
3353 const char *username,
3354 GCancellable *cancellable,
3355 GAsyncReadyCallback callback,
3356 gpointer user_data)
3357 {
3358 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3359 GTask *task;
3360
3361 g_return_if_fail (ACT_IS_USER_MANAGER (manager));
3362 g_return_if_fail (priv->accounts_proxy != NULL);
3363
3364 g_debug ("ActUserManager: Caching user (async) '%s'", username);
3365
3366 task = g_task_new (G_OBJECT (manager),
3367 cancellable,
3368 callback, user_data);
3369
3370 accounts_accounts_call_cache_user (priv->accounts_proxy,
3371 username,
3372 cancellable,
3373 act_user_manager_async_complete_handler, task);
3374 }
3375
3376 /**
3377 * act_user_manager_cache_user_finish:
3378 * @manager: a #ActUserManager
3379 * @result: a #GAsyncResult
3380 * @error: a #GError
3381 *
3382 * Finishes an asynchronous user caching.
3383 *
3384 * See act_user_manager_cache_user_async().
3385 *
3386 * Returns: (transfer full): user object
3387 *
3388 * Since: 0.6.27
3389 */
3390 ActUser *
act_user_manager_cache_user_finish(ActUserManager * manager,GAsyncResult * result,GError ** error)3391 act_user_manager_cache_user_finish (ActUserManager *manager,
3392 GAsyncResult *result,
3393 GError **error)
3394 {
3395 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3396 GAsyncResult *inner_result;
3397 ActUser *user = NULL;
3398 g_autofree gchar *path = NULL;
3399 GError *remote_error = NULL;
3400
3401 inner_result = g_task_propagate_pointer (G_TASK (result), error);
3402 if (inner_result == NULL) {
3403 return FALSE;
3404 }
3405
3406 if (accounts_accounts_call_cache_user_finish (priv->accounts_proxy,
3407 &path, inner_result, &remote_error)) {
3408 user = add_new_user_for_object_path (path, manager);
3409 }
3410
3411 if (remote_error) {
3412 g_dbus_error_strip_remote_error (remote_error);
3413 g_propagate_error (error, remote_error);
3414 }
3415
3416 return user;
3417 }
3418
3419 /**
3420 * act_user_manager_uncache_user:
3421 * @manager: a #ActUserManager
3422 * @username: a user name
3423 * @error: a #GError
3424 *
3425 * Releases all metadata about a user account, including icon,
3426 * language and session. If the user account is from a remote
3427 * server and the user has never logged in before, then that
3428 * account will no longer show up in ListCachedUsers() output.
3429 *
3430 * Returns: %TRUE if successful, otherwise %FALSE
3431 */
3432 gboolean
act_user_manager_uncache_user(ActUserManager * manager,const char * username,GError ** error)3433 act_user_manager_uncache_user (ActUserManager *manager,
3434 const char *username,
3435 GError **error)
3436 {
3437 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3438 GError *local_error = NULL;
3439 gboolean res;
3440
3441 g_debug ("ActUserManager: Uncaching user '%s'",
3442 username);
3443
3444 g_assert (priv->accounts_proxy != NULL);
3445
3446 res = accounts_accounts_call_uncache_user_sync (priv->accounts_proxy,
3447 username,
3448 NULL,
3449 &local_error);
3450 if (!res) {
3451 g_propagate_error (error, local_error);
3452 return FALSE;
3453 }
3454
3455 return TRUE;
3456 }
3457
3458 /*
3459 * act_user_manager_uncache_user_async:
3460 * @manager: a #ActUserManager
3461 * @username: a unix user name
3462 * @cancellable: (allow-none): optional #GCancellable object,
3463 * %NULL to ignore
3464 * @callback: (scope async): a #GAsyncReadyCallback to call
3465 * when the request is satisfied
3466 * @user_data: (closure): the data to pass to @callback
3467 *
3468 * Asynchronously uncaches a user account.
3469 *
3470 * For more details, see act_user_manager_uncache_user(), which
3471 * is the synchronous version of this call.
3472 *
3473 * Since: 0.6.39
3474 */
3475 void
act_user_manager_uncache_user_async(ActUserManager * manager,const char * username,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)3476 act_user_manager_uncache_user_async (ActUserManager *manager,
3477 const char *username,
3478 GCancellable *cancellable,
3479 GAsyncReadyCallback callback,
3480 gpointer user_data)
3481 {
3482 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3483 GTask *task;
3484
3485 g_return_if_fail (ACT_IS_USER_MANAGER (manager));
3486 g_return_if_fail (username != NULL);
3487 g_return_if_fail (priv->accounts_proxy != NULL);
3488
3489 g_debug ("ActUserManager: Uncaching user (async) '%s'", username);
3490
3491 task = g_task_new (G_OBJECT (manager),
3492 cancellable,
3493 callback, user_data);
3494
3495 accounts_accounts_call_uncache_user (priv->accounts_proxy,
3496 username,
3497 cancellable,
3498 act_user_manager_async_complete_handler, task);
3499 }
3500
3501 /**
3502 * act_user_manager_uncache_user_finish:
3503 * @manager: a #ActUserManager
3504 * @result: a #GAsyncResult
3505 * @error: a #GError
3506 *
3507 * Finishes an asynchronous user uncaching.
3508 *
3509 * See act_user_manager_uncache_user_async().
3510 *
3511 * Returns: %TRUE if the user account was successfully uncached
3512 *
3513 * Since: 0.6.39
3514 */
3515 gboolean
act_user_manager_uncache_user_finish(ActUserManager * manager,GAsyncResult * result,GError ** error)3516 act_user_manager_uncache_user_finish (ActUserManager *manager,
3517 GAsyncResult *result,
3518 GError **error)
3519 {
3520 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3521 GAsyncResult *inner_result;
3522 gboolean success;
3523 GError *remote_error = NULL;
3524
3525 inner_result = g_task_propagate_pointer (G_TASK (result), error);
3526 if (inner_result == NULL) {
3527 return FALSE;
3528 }
3529
3530 success = accounts_accounts_call_uncache_user_finish (priv->accounts_proxy,
3531 inner_result, &remote_error);
3532
3533 if (remote_error) {
3534 g_dbus_error_strip_remote_error (remote_error);
3535 g_propagate_error (error, remote_error);
3536 }
3537
3538 return success;
3539 }
3540
3541 /**
3542 * act_user_manager_delete_user:
3543 * @manager: a #ActUserManager
3544 * @user: an #ActUser object
3545 * @remove_files: %TRUE to delete the users home directory
3546 * @error: a #GError
3547 *
3548 * Deletes a user account on the system.
3549 *
3550 * Returns: %TRUE if the user account was successfully deleted
3551 */
3552 gboolean
act_user_manager_delete_user(ActUserManager * manager,ActUser * user,gboolean remove_files,GError ** error)3553 act_user_manager_delete_user (ActUserManager *manager,
3554 ActUser *user,
3555 gboolean remove_files,
3556 GError **error)
3557 {
3558 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3559 GError *local_error = NULL;
3560
3561 g_debug ("ActUserManager: Deleting user '%s' (uid %ld)", act_user_get_user_name (user), (long) act_user_get_uid (user));
3562
3563 g_return_val_if_fail (ACT_IS_USER_MANAGER (manager), FALSE);
3564 g_return_val_if_fail (ACT_IS_USER (user), FALSE);
3565 g_return_val_if_fail (priv->accounts_proxy != NULL, FALSE);
3566
3567 if (!accounts_accounts_call_delete_user_sync (priv->accounts_proxy,
3568 act_user_get_uid (user),
3569 remove_files,
3570 NULL,
3571 &local_error)) {
3572 g_propagate_error (error, local_error);
3573 return FALSE;
3574 }
3575
3576 return TRUE;
3577 }
3578
3579 /**
3580 * act_user_manager_delete_user_async:
3581 * @manager: a #ActUserManager
3582 * @user: a #ActUser object
3583 * @remove_files: %TRUE to delete the users home directory
3584 * @cancellable: (allow-none): optional #GCancellable object,
3585 * %NULL to ignore
3586 * @callback: (scope async): a #GAsyncReadyCallback to call
3587 * when the request is satisfied
3588 * @user_data: (closure): the data to pass to @callback
3589 *
3590 * Asynchronously deletes a user account from the system.
3591 *
3592 * For more details, see act_user_manager_delete_user(), which
3593 * is the synchronous version of this call.
3594 *
3595 * Since: 0.6.27
3596 */
3597 void
act_user_manager_delete_user_async(ActUserManager * manager,ActUser * user,gboolean remove_files,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)3598 act_user_manager_delete_user_async (ActUserManager *manager,
3599 ActUser *user,
3600 gboolean remove_files,
3601 GCancellable *cancellable,
3602 GAsyncReadyCallback callback,
3603 gpointer user_data)
3604 {
3605 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3606 GTask *task;
3607
3608 g_return_if_fail (ACT_IS_USER_MANAGER (manager));
3609 g_return_if_fail (ACT_IS_USER (user));
3610 g_return_if_fail (priv->accounts_proxy != NULL);
3611
3612 task = g_task_new (G_OBJECT (manager),
3613 cancellable,
3614 callback, user_data);
3615
3616 g_debug ("ActUserManager: Deleting (async) user '%s' (uid %ld)", act_user_get_user_name (user), (long) act_user_get_uid (user));
3617
3618 accounts_accounts_call_delete_user (priv->accounts_proxy,
3619 act_user_get_uid (user), remove_files,
3620 cancellable,
3621 act_user_manager_async_complete_handler, task);
3622 }
3623
3624 /**
3625 * act_user_manager_delete_user_finish:
3626 * @manager: a #ActUserManager
3627 * @result: a #GAsyncResult
3628 * @error: a #GError
3629 *
3630 * Finishes an asynchronous user account deletion.
3631 *
3632 * See act_user_manager_delete_user_async().
3633 *
3634 * Returns: %TRUE if the user account was successfully deleted
3635 *
3636 * Since: 0.6.27
3637 */
3638 gboolean
act_user_manager_delete_user_finish(ActUserManager * manager,GAsyncResult * result,GError ** error)3639 act_user_manager_delete_user_finish (ActUserManager *manager,
3640 GAsyncResult *result,
3641 GError **error)
3642 {
3643 ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager);
3644 GAsyncResult *inner_result;
3645 gboolean success;
3646 GError *remote_error = NULL;
3647
3648 inner_result = g_task_propagate_pointer (G_TASK (result), error);
3649 if (inner_result == NULL) {
3650 return FALSE;
3651 }
3652
3653 success = accounts_accounts_call_delete_user_finish (priv->accounts_proxy,
3654 inner_result, &remote_error);
3655 if (remote_error) {
3656 g_dbus_error_strip_remote_error (remote_error);
3657 g_propagate_error (error, remote_error);
3658 }
3659
3660 return success;
3661 }
3662