tizen: release 0.0.4
[platform/core/system/tlm.git] / src / daemon / tlm-manager.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of tlm (Tizen Login Manager)
5  *
6  * Copyright (C) 2013 Intel Corporation.
7  *
8  * Contact: Amarnath Valluri <amarnath.valluri@linux.intel.com>
9  *          Jussi Laako <jussi.laako@linux.intel.com>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24  * 02110-1301 USA
25  */
26
27 #include "tlm-manager.h"
28 #include "tlm-seat.h"
29 #include "tlm-log.h"
30 #include "tlm-account-plugin.h"
31 #include "tlm-auth-plugin.h"
32 #include "tlm-config.h"
33 #include "tlm-config-general.h"
34 #include "tlm-dbus-observer.h"
35 #include "tlm-utils.h"
36 #include "config.h"
37
38 #include <glib.h>
39 #include <gio/gio.h>
40 #include <stdio.h>
41 #include <string.h>
42
43 G_DEFINE_TYPE (TlmManager, tlm_manager, G_TYPE_OBJECT);
44
45 #define TLM_MANAGER_PRIV(obj) \
46     G_TYPE_INSTANCE_GET_PRIVATE ((obj), TLM_TYPE_MANAGER, TlmManagerPrivate)
47
48 #define LOGIND_BUS_NAME         "org.freedesktop.login1"
49 #define LOGIND_OBJECT_PATH      "/org/freedesktop/login1"
50 #define LOGIND_MANAGER_IFACE    LOGIND_BUS_NAME".Manager"
51
52 struct _TlmManagerPrivate
53 {
54     GDBusConnection *connection;
55     TlmConfig *config;
56     GHashTable *seats; /* { gchar*:TlmSeat* } */
57     TlmDbusObserver *dbus_observer; /* dbus observer accessed by root only */
58     TlmAccountPlugin *account_plugin;
59     GList *auth_plugins;
60     gboolean is_started;
61     gchar *initial_user;
62
63     guint seat_added_id;
64     guint seat_removed_id;
65 };
66
67 enum {
68     PROP_0,
69     PROP_INITIAL_USER,
70     N_PROPERTIES
71 };
72 static GParamSpec *pspecs[N_PROPERTIES];
73
74 enum {
75     SIG_SEAT_ADDED,
76     SIG_SEAT_REMOVED,
77     SIG_MANAGER_STOPPED,
78     SIG_MAX,
79 };
80
81 static guint signals[SIG_MAX];
82
83 static void
84 _unref_auth_plugins (gpointer data)
85 {
86         GObject *plugin = G_OBJECT (data);
87
88         g_object_unref (plugin);
89 }
90
91 static void
92 tlm_manager_dispose (GObject *self)
93 {
94     TlmManager *manager = TLM_MANAGER(self);
95
96     DBG("disposing manager");
97
98     if (manager->priv->dbus_observer) {
99         g_object_unref (manager->priv->dbus_observer);
100         manager->priv->dbus_observer = NULL;
101     }
102
103     if (manager->priv->is_started) {
104         tlm_manager_stop (manager);
105     }
106
107     if (manager->priv->seats) {
108         g_hash_table_unref (manager->priv->seats);
109         manager->priv->seats = NULL;
110     }
111
112     g_clear_object (&manager->priv->account_plugin);
113     g_clear_object (&manager->priv->config);
114
115     if (manager->priv->auth_plugins) {
116         g_list_free_full(manager->priv->auth_plugins, _unref_auth_plugins);
117     }
118
119     g_clear_string (&manager->priv->initial_user);
120
121     G_OBJECT_CLASS (tlm_manager_parent_class)->dispose (self);
122 }
123
124 static void
125 tlm_manager_finalize (GObject *self)
126 {
127     G_OBJECT_CLASS (tlm_manager_parent_class)->finalize (self);
128 }
129
130 static void
131 _manager_set_property (GObject *obj,
132                        guint property_id,
133                        const GValue *value,
134                        GParamSpec *pspec)
135 {
136     TlmManager *manager = TLM_MANAGER (obj);
137
138     switch (property_id) {
139         case PROP_INITIAL_USER:
140             manager->priv->initial_user = g_value_dup_string (value);
141             break;
142         default:
143             G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
144     }
145 }
146
147 static void
148 _manager_get_property (GObject *obj,
149                        guint property_id,
150                        GValue *value,
151                        GParamSpec *pspec)
152 {
153     TlmManager *manager = TLM_MANAGER (obj);
154
155     switch (property_id) {
156         case PROP_INITIAL_USER:
157             g_value_set_string (value, manager->priv->initial_user);
158             break;
159         default:
160             G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
161     }
162 }
163
164 static GObject *
165 tlm_manager_constructor (GType gtype, guint n_prop, GObjectConstructParam *prop)
166 {
167     static GObject *manager = NULL; /* Singleton */
168
169     if (manager != NULL) return g_object_ref (manager);
170
171     manager = G_OBJECT_CLASS (tlm_manager_parent_class)->
172                                     constructor (gtype, n_prop, prop);
173     g_object_add_weak_pointer (G_OBJECT(manager), (gpointer*)&manager);
174     
175     return manager;
176 }
177
178 static void
179 tlm_manager_class_init (TlmManagerClass *klass)
180 {
181     GObjectClass *g_klass = G_OBJECT_CLASS (klass);
182
183     g_type_class_add_private (klass, sizeof(TlmManagerPrivate));
184
185     g_klass->constructor = tlm_manager_constructor;    
186     g_klass->dispose = tlm_manager_dispose ;
187     g_klass->finalize = tlm_manager_finalize;
188     g_klass->set_property = _manager_set_property;
189     g_klass->get_property = _manager_get_property;
190
191     pspecs[PROP_INITIAL_USER] =
192         g_param_spec_string ("initial-user",
193                              "initial user",
194                              "User name for initial auto-login",
195                              NULL,
196                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_STATIC_STRINGS);
197     g_object_class_install_properties (g_klass, N_PROPERTIES, pspecs);
198
199     signals[SIG_SEAT_ADDED] =  g_signal_new ("seat-added",
200                                              TLM_TYPE_MANAGER,
201                                              G_SIGNAL_RUN_LAST,
202                                              0,
203                                              NULL,
204                                              NULL,
205                                              NULL,
206                                              G_TYPE_NONE,
207                                              1,
208                                              TLM_TYPE_SEAT);
209
210     signals[SIG_SEAT_REMOVED] =  g_signal_new ("seat-removed",
211                                                TLM_TYPE_MANAGER,
212                                                G_SIGNAL_RUN_LAST,
213                                                0,
214                                                NULL,
215                                                NULL,
216                                                NULL,
217                                                G_TYPE_NONE,
218                                                1,
219                                                G_TYPE_STRING);
220     signals[SIG_MANAGER_STOPPED] = g_signal_new ("manager-stopped",
221                                                  TLM_TYPE_MANAGER,
222                                                  G_SIGNAL_RUN_LAST,
223                                                  0,
224                                                  NULL,
225                                                  NULL,
226                                                  NULL,
227                                                  G_TYPE_NONE,
228                                                  0);
229 }
230
231 static gboolean
232 _manager_authenticate_cb (TlmAuthPlugin *plugin,
233                           const gchar *seat_id,
234                           const gchar *pam_service,
235                           const gchar *username,
236                           const gchar *password,
237                           gpointer user_data)
238 {
239     TlmManager *self = TLM_MANAGER (user_data);
240     TlmSeat *seat = NULL;
241
242     g_return_val_if_fail (self, FALSE);
243
244     DBG ("'%s' '%s' '%s' '%s'", seat_id, pam_service, username, password);
245
246     seat = g_hash_table_lookup (self->priv->seats, seat_id);
247     if (!seat) {
248         WARN ("Seat is not ready : %s", seat_id);
249         return FALSE;
250     }
251
252     /* re login with new username */
253     return tlm_seat_switch_user (seat, pam_service, username, password, NULL);
254 }
255
256 static GObject *
257 _load_plugin_file (const gchar *file_path, 
258                    const gchar *plugin_name,
259                    const gchar *plugin_type,
260                    GHashTable *config)
261 {
262     GObject *plugin = NULL;
263
264     DBG("Loading plugin %s", file_path);
265     GModule* plugin_module = g_module_open (file_path, G_MODULE_BIND_LAZY);
266     if (plugin_module == NULL) {
267         DBG("Plugin couldn't be opened: %s", g_module_error());
268         return NULL;
269     }
270
271     gchar* get_type_func = g_strdup_printf("tlm_%s_plugin_%s_get_type", 
272                                            plugin_type,
273                                            plugin_name);
274     gpointer p;
275
276     DBG("Resolving symbol %s", get_type_func);
277     gboolean symfound = g_module_symbol (plugin_module, get_type_func, &p);
278     g_free(get_type_func);
279     if (!symfound) {
280         DBG("Symbol couldn't be resolved");
281         g_module_close (plugin_module);
282         return NULL;
283     }
284
285     DBG("Creating plugin object");
286     GType (*plugin_get_type_f)(void) = p;
287     plugin = g_object_new(plugin_get_type_f(), "config", config, NULL);
288     if (plugin == NULL) {
289         DBG("Plugin couldn't be created");
290         g_module_close (plugin_module);
291         return NULL;
292     }
293     g_module_make_resident (plugin_module);
294
295     return plugin;
296 }
297
298 static const gchar*
299 _get_plugins_path ()
300 {
301     const gchar *e_val = NULL;
302
303     e_val = g_getenv ("TLM_PLUGINS_DIR");
304     if (!e_val) return TLM_PLUGINS_DIR;
305
306     return e_val;
307 }
308
309 static void
310 _load_accounts_plugin (TlmManager *self, const gchar *name)
311 {
312     const gchar *plugins_path = NULL;
313     gchar *plugin_file = NULL;
314     gchar *plugin_file_name = NULL;
315     GHashTable *accounts_config = NULL;
316
317     plugins_path = _get_plugins_path ();
318
319     accounts_config = tlm_config_get_group (self->priv->config, name);
320
321     plugin_file_name = g_strdup_printf ("libtlm-plugin-%s", name);
322     plugin_file = g_module_build_path(plugins_path, plugin_file_name);
323     g_free (plugin_file_name);
324
325     self->priv->account_plugin =  TLM_ACCOUNT_PLUGIN(
326         _load_plugin_file (plugin_file, name, "account", accounts_config));
327
328     g_free (plugin_file);
329 }
330
331 static void
332 _load_auth_plugins (TlmManager *self)
333 {
334     const gchar *plugins_path = NULL;
335     const gchar *plugin_file_name = NULL;
336     GDir  *plugins_dir = NULL;
337     GError *error = NULL;
338
339     plugins_path = _get_plugins_path ();
340     
341     DBG("plugins_path : %s", plugins_path);
342     plugins_dir = g_dir_open (plugins_path, 0, &error);
343     if (!plugins_dir) {
344         WARN ("Failed to open pluins folder '%s' : %s", plugins_path,
345                  error ? error->message : "NULL");
346         g_error_free (error);
347         return;
348     }
349
350     while ((plugin_file_name = g_dir_read_name (plugins_dir)) != NULL)
351     {
352         DBG("Plugin File : %s", plugin_file_name);
353         if (g_str_has_prefix (plugin_file_name, "libtlm-plugin-") &&
354             g_str_has_suffix (plugin_file_name, ".so"))
355         {
356             gchar      *plugin_file_path = NULL;
357             gchar      *plugin_name = NULL;
358             GHashTable *plugin_config = NULL;
359             GObject    *plugin = NULL;
360         
361             plugin_file_path = g_module_build_path(plugins_path, 
362                                                    plugin_file_name);
363
364             if (!g_file_test (plugin_file_path, 
365                               G_FILE_TEST_IS_REGULAR && G_FILE_TEST_EXISTS)) {
366                 WARN ("Ingnoring plugin : %s", plugin_file_path);
367                 g_free (plugin_file_path);
368                 continue;
369             }
370
371             DBG ("loading auth plugin '%s'", plugin_file_name);
372  
373             plugin_name = g_strdup (plugin_file_name + 14); // truncate prefix
374             plugin_name[strlen(plugin_name) - 3] = '\0' ; // truncate suffix
375
376             plugin_config = tlm_config_get_group (self->priv->config,
377                                                   plugin_name);
378     
379             plugin = _load_plugin_file (plugin_file_path,
380                                         plugin_name, 
381                                         "auth",
382                                         plugin_config);
383             if (plugin) {
384                 g_signal_connect (plugin, "authenticate",
385                      G_CALLBACK(_manager_authenticate_cb), self);
386                 self->priv->auth_plugins = g_list_append (
387                             self->priv->auth_plugins, plugin);
388             }
389             g_free (plugin_file_path);
390             g_free (plugin_name);
391         }
392     }
393
394     g_dir_close (plugins_dir);
395
396 }
397
398 static void
399 tlm_manager_init (TlmManager *manager)
400 {
401     GError *error = NULL;
402     TlmManagerPrivate *priv = TLM_MANAGER_PRIV (manager);
403     
404     priv->config = tlm_config_new ();
405     priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
406     if (!priv->connection) {
407         CRITICAL ("error getting system bus: %s", error->message);
408         g_error_free (error);
409         return;
410     }
411
412     priv->seats = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
413                                          (GDestroyNotify)g_object_unref);
414
415     priv->account_plugin = NULL;
416     priv->auth_plugins = NULL;
417
418     manager->priv = priv;
419
420     _load_accounts_plugin (manager, tlm_config_get_string (priv->config,
421             TLM_CONFIG_GENERAL, TLM_CONFIG_GENERAL_ACCOUNTS_PLUGIN));
422     _load_auth_plugins (manager);
423
424     /* delete tlm runtime directory */
425     tlm_utils_delete_dir (TLM_DBUS_SOCKET_PATH);
426     priv->dbus_observer = TLM_DBUS_OBSERVER (tlm_dbus_observer_new (manager,
427             NULL, TLM_DBUS_ROOT_SOCKET_ADDRESS, getuid (),
428             DBUS_OBSERVER_ENABLE_ALL));
429 }
430
431 static void
432 _prepare_user_cb (TlmSeat *seat, const gchar *user_name, gpointer user_data)
433 {
434     TlmManager *manager = TLM_MANAGER(user_data);
435
436     g_return_if_fail (user_data && TLM_IS_MANAGER(manager));
437
438     if (tlm_config_get_boolean (manager->priv->config,
439                                 TLM_CONFIG_GENERAL,
440                                 TLM_CONFIG_GENERAL_PREPARE_DEFAULT,
441                                 FALSE)) {
442         DBG ("prepare for '%s'", user_name);
443         if (!tlm_manager_setup_guest_user (manager, user_name)) {
444             WARN ("failed to prepare for '%s'", user_name);
445         }
446     }
447 }
448
449 static void
450 _add_seat (TlmManager *manager, const gchar *seat_id, const gchar *seat_path)
451 {
452     g_return_if_fail (manager && TLM_IS_MANAGER (manager));
453
454     TlmManagerPrivate *priv = TLM_MANAGER_PRIV (manager);
455
456     TlmSeat *seat = tlm_seat_new (priv->config,
457                                   seat_id,
458                                   seat_path);
459     g_signal_connect (seat,
460                       "prepare-user",
461                       G_CALLBACK (_prepare_user_cb),
462                       manager);
463
464     g_hash_table_insert (priv->seats, g_strdup (seat_id), seat);
465
466     g_signal_emit (manager, signals[SIG_SEAT_ADDED], 0, seat, NULL);
467
468     if (tlm_config_get_boolean (priv->config,
469                                 TLM_CONFIG_GENERAL,
470                                 TLM_CONFIG_GENERAL_AUTO_LOGIN,
471                                 TRUE) ||
472         priv->initial_user) {
473         DBG("intial auto-login for user '%s'", priv->initial_user);
474         if (!tlm_seat_create_session (seat,
475                                       NULL,
476                                       priv->initial_user,
477                                       NULL,
478                                       NULL))
479             WARN("Failed to create session for default user");
480     }
481 }
482
483 static void
484 _manager_hashify_seats (TlmManager *manager, GVariant *hash_map)
485 {
486     GVariantIter iter;
487     gchar *id = 0, *path = 0;
488
489     g_return_if_fail (manager);
490     g_return_if_fail (hash_map);
491
492     g_variant_iter_init (&iter, hash_map);
493     while (g_variant_iter_next (&iter, "(so)", &id, &path)) {
494         DBG("found seat %s:%s", id, path);
495         _add_seat (manager, id, path);
496         g_free (id);
497         g_free (path);
498     }
499 }
500
501 static void
502 _manager_sync_seats (TlmManager *manager)
503 {
504     GError *error = NULL;
505     GVariant *reply = NULL;
506     GVariant *hash_map = NULL;
507
508     g_return_if_fail (manager && manager->priv->connection);
509
510     reply = g_dbus_connection_call_sync (manager->priv->connection,
511                                          LOGIND_BUS_NAME,
512                                          LOGIND_OBJECT_PATH,
513                                          LOGIND_MANAGER_IFACE,
514                                          "ListSeats",
515                                          g_variant_new("()"),
516                                          G_VARIANT_TYPE_TUPLE,
517                                          G_DBUS_CALL_FLAGS_NONE,
518                                          -1,
519                                          NULL,
520                                          &error);
521     if (!reply) {
522         WARN ("failed to get attached seats: %s", error->message);
523         g_error_free (error);
524         return;
525     }
526
527     g_variant_get (reply, "(@a(so))", &hash_map);
528     g_variant_unref (reply);
529
530     _manager_hashify_seats (manager, hash_map);
531
532     g_variant_unref (hash_map);
533 }
534
535 static void
536 _manager_on_seat_added (GDBusConnection *connection,
537                         const gchar *sender,
538                         const gchar *object_path,
539                         const gchar *iface,
540                         const gchar *signal_name,
541                         GVariant *params,
542                         gpointer userdata)
543 {
544     gchar *id = NULL, *path = NULL;
545     TlmManager *manager = TLM_MANAGER (userdata);
546
547     g_return_if_fail (manager);
548     g_return_if_fail (params);
549
550     g_variant_get (params, "(&s&o)", &id, &path);
551     g_variant_unref (params);
552
553     DBG("Seat added: %s:%s", id, path);
554
555     if (!g_hash_table_contains (manager->priv->seats, id)) {
556         _add_seat (manager, id, path);
557     }
558     g_free (id);
559     g_free (path);
560 }
561
562 static void
563 _manager_on_seat_removed (GDBusConnection *connection,
564                         const gchar *sender,
565                         const gchar *object_path,
566                         const gchar *iface,
567                         const gchar *signal_name,
568                         GVariant *params,
569                         gpointer userdata)
570 {
571     gchar *id = NULL, *path = NULL;
572     TlmManager *manager = TLM_MANAGER (userdata);
573
574     g_return_if_fail (manager);
575     g_return_if_fail (params);
576
577     g_variant_get (params, "(&s&o)", &id, path);
578     g_variant_unref (params);
579
580     DBG("Seat removed: %s:%s", id, path);
581
582     if (!g_hash_table_contains (manager->priv->seats, id)) {
583         g_hash_table_remove (manager->priv->seats, id);
584         g_signal_emit (manager, signals[SIG_SEAT_REMOVED], 0, id, NULL);
585
586     } 
587     g_free (id);
588     g_free (path);
589 }
590
591 static void
592 _manager_subscribe_seat_changes (TlmManager *manager)
593 {
594     TlmManagerPrivate *priv = manager->priv;
595
596     priv->seat_added_id = g_dbus_connection_signal_subscribe (
597                               priv->connection,
598                               LOGIND_BUS_NAME,
599                               LOGIND_MANAGER_IFACE,
600                               "SeatNew",
601                               LOGIND_OBJECT_PATH,
602                               NULL,
603                               G_DBUS_SIGNAL_FLAGS_NONE,
604                               _manager_on_seat_added,
605                               manager, NULL);
606
607     priv->seat_removed_id = g_dbus_connection_signal_subscribe (
608                                 priv->connection,
609                                 LOGIND_BUS_NAME,
610                                 LOGIND_MANAGER_IFACE,
611                                 "SeatRemoved",
612                                 LOGIND_OBJECT_PATH,
613                                 NULL,
614                                 G_DBUS_SIGNAL_FLAGS_NONE,
615                                 _manager_on_seat_removed,
616                                 manager, NULL);
617 }
618
619 static void
620 _manager_unsubsribe_seat_changes (TlmManager *manager)
621 {
622     if (manager->priv->seat_added_id) {
623         g_dbus_connection_signal_unsubscribe (manager->priv->connection,
624                                               manager->priv->seat_added_id);
625         manager->priv->seat_added_id = 0;
626     }
627
628     if (manager->priv->seat_removed_id) {
629         g_dbus_connection_signal_unsubscribe (manager->priv->connection,
630                                               manager->priv->seat_removed_id);
631         manager->priv->seat_removed_id = 0;
632     }
633 }
634
635 gboolean
636 tlm_manager_start (TlmManager *manager)
637 {
638     g_return_val_if_fail (manager && TLM_IS_MANAGER (manager), FALSE);
639
640     _manager_sync_seats (manager);
641     _manager_subscribe_seat_changes (manager);
642
643     manager->priv->is_started = TRUE;
644
645     return TRUE;
646 }
647
648
649 static gboolean
650 _session_terminated_cb (GObject *emitter, const gchar *seat_id,
651         TlmManager *manager)
652 {
653     g_return_val_if_fail (manager && TLM_IS_MANAGER (manager), TRUE);
654     DBG("seatid %s", seat_id);
655
656     g_hash_table_remove (manager->priv->seats, seat_id);
657     if (g_hash_table_size (manager->priv->seats) == 0) {
658         DBG ("signalling stopped");
659         g_signal_emit (manager, signals[SIG_MANAGER_STOPPED], 0);
660     }
661
662     return TRUE;
663 }
664
665 gboolean
666 tlm_manager_stop (TlmManager *manager)
667 {
668     g_return_val_if_fail (manager && TLM_IS_MANAGER (manager), FALSE);
669
670     _manager_unsubsribe_seat_changes (manager);
671
672     GHashTableIter iter;
673     gpointer key, value;
674     gboolean delayed = FALSE;
675
676     g_hash_table_iter_init (&iter, manager->priv->seats);
677     while (g_hash_table_iter_next (&iter, &key, &value)) {
678         DBG ("terminate seat '%s'", (const gchar *) key);
679         g_signal_connect_after ((TlmSeat *) value,
680                                   "session-terminated",
681                                   G_CALLBACK (_session_terminated_cb),
682                                   manager);
683         if (!tlm_seat_terminate_session ((TlmSeat *) value)) {
684             g_hash_table_remove (manager->priv->seats, key);
685             g_hash_table_iter_init (&iter, manager->priv->seats);
686         } else {
687             delayed = TRUE;
688         }
689     }
690     if (!delayed)
691         g_signal_emit (manager, signals[SIG_MANAGER_STOPPED], 0);
692
693     manager->priv->is_started = FALSE;
694
695     return TRUE;
696 }
697
698 gboolean
699 tlm_manager_setup_guest_user (TlmManager *manager, const gchar *user_name)
700 {
701     g_return_val_if_fail (manager && TLM_IS_MANAGER (manager), FALSE);
702     g_return_val_if_fail (manager->priv->account_plugin, FALSE);
703
704     if (tlm_account_plugin_is_valid_user (
705             manager->priv->account_plugin, user_name)) {
706         DBG("user account '%s' already existing, cleaning the home folder",
707                  user_name);
708         return tlm_account_plugin_cleanup_guest_user (
709                     manager->priv->account_plugin, user_name, FALSE);
710     }
711     else {
712         DBG("Asking plugin to setup guest user '%s'", user_name); 
713         return tlm_account_plugin_setup_guest_user_account (
714                     manager->priv->account_plugin, user_name);
715     }
716 }
717
718 TlmManager *
719 tlm_manager_new (const gchar *initial_user)
720 {
721     return g_object_new (TLM_TYPE_MANAGER,
722                          "initial-user", initial_user,
723                          NULL);
724 }
725
726 TlmSeat *
727 tlm_manager_get_seat (TlmManager *manager, const gchar *seat_id)
728 {
729     g_return_val_if_fail (manager && TLM_IS_MANAGER (manager), NULL);
730
731     return g_hash_table_lookup (manager->priv->seats, seat_id);
732 }
733
734 void
735 tlm_manager_sighup_received (TlmManager *manager)
736 {
737     g_return_if_fail (manager && TLM_IS_MANAGER (manager));
738
739     DBG ("sighup recvd. reload configuration and account plugin");
740     tlm_config_reload (manager->priv->config);
741     g_clear_object (&manager->priv->account_plugin);
742     _load_accounts_plugin (manager, tlm_config_get_string (
743             manager->priv->config, TLM_CONFIG_GENERAL,
744             TLM_CONFIG_GENERAL_ACCOUNTS_PLUGIN));
745 }