64ec5f62ef0fd0e21b208a9aa1800c845d6de574
[platform/core/system/tlm.git] / src / daemon / tlm-seat.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 (Tiny Login Manager)
5  *
6  * Copyright (C) 2013-2014 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 <string.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31
32 #include <tzplatform_config.h>
33
34 #include "config.h"
35
36 #include "tlm-seat.h"
37 #include "tlm-session-remote.h"
38 #include "tlm-log.h"
39 #include "tlm-error.h"
40 #include "tlm-utils.h"
41 #include "tlm-config-general.h"
42 #include "tlm-dbus-observer.h"
43
44 G_DEFINE_TYPE (TlmSeat, tlm_seat, G_TYPE_OBJECT);
45
46 #define TLM_SEAT_PRIV(obj) \
47     G_TYPE_INSTANCE_GET_PRIVATE ((obj), TLM_TYPE_SEAT, TlmSeatPrivate)
48
49 enum {
50     PROP_0,
51     PROP_CONFIG,
52     PROP_ID,
53     PROP_PATH,
54     N_PROPERTIES
55 };
56 static GParamSpec *pspecs[N_PROPERTIES];
57
58 enum {
59     SIG_PREPARE_USER_LOGIN,
60     SIG_PREPARE_USER_LOGOUT,
61     SIG_SESSION_CREATED,
62     SIG_SESSION_TERMINATED,
63     SIG_SESSION_ERROR,
64     SIG_MAX
65 };
66 static guint signals[SIG_MAX];
67
68 struct _TlmSeatPrivate
69 {
70     TlmConfig *config;
71     gchar *id;
72     gchar *default_user;
73     gchar *path;
74     gchar *next_service;
75     gchar *next_user;
76     gchar *next_password;
77     GHashTable *next_environment;
78     gint64 prev_time;
79     gint32 prev_count;
80     gboolean default_active;
81     TlmSessionRemote *session;
82     TlmDbusObserver *dbus_observer; /* dbus server accessed only by user who has
83     active session */
84     TlmDbusObserver *prev_dbus_observer;
85     gboolean manager_stop;
86 };
87
88 typedef struct _DelayClosure
89 {
90     TlmSeat *seat;
91     gchar *service;
92     gchar *username;
93     gchar *password;
94     GHashTable *environment;
95 } DelayClosure;
96
97 static void
98 _disconnect_session_signals (
99         TlmSeat *seat);
100
101 static void
102 _reset_next (TlmSeatPrivate *priv)
103 {
104     g_clear_string (&priv->next_service);
105     g_clear_string (&priv->next_user);
106     g_clear_string (&priv->next_password);
107     if (priv->next_environment) {
108         g_hash_table_unref (priv->next_environment);
109         priv->next_environment = NULL;
110     }
111 }
112
113 static void
114 _handle_session_created (
115         TlmSeat *self,
116         const gchar *sessionid,
117         gpointer user_data)
118 {
119     g_return_if_fail (self && TLM_IS_SEAT (self));
120
121     DBG ("sessionid: %s", sessionid);
122
123     g_signal_emit (self, signals[SIG_SESSION_CREATED], 0, self->priv->id);
124
125     g_clear_object (&self->priv->prev_dbus_observer);
126 }
127
128 static void
129 _close_active_session (TlmSeat *self)
130 {
131     TlmSeatPrivate *priv = TLM_SEAT_PRIV (self);
132     _disconnect_session_signals (self);
133     if (priv->session) {
134         DBG("Clear session_remote object");
135         g_clear_object (&priv->session);
136     }
137 }
138
139 static void
140 _handle_session_terminated (
141         TlmSeat *self,
142         gpointer user_data)
143 {
144     g_return_if_fail (self && TLM_IS_SEAT (self));
145
146     TlmSeat *seat = TLM_SEAT(self);
147     TlmSeatPrivate *priv = TLM_SEAT_PRIV(seat);
148     gboolean stop = FALSE;
149
150     DBG ("seat %p session %p", self, priv->session);
151
152     _close_active_session (seat);
153
154     // NOTE: This "session-terminated" signal to seat object is caught by
155     // _session_terminated_cb() which is conencted in tlm_manager_stop().
156     g_signal_emit (seat,
157             signals[SIG_SESSION_TERMINATED],
158             0,
159             priv->id,
160             &stop);
161     if (stop) {
162         DBG ("no relogin or switch user");
163         return;
164     }
165
166     g_clear_object (&priv->dbus_observer);
167
168     // If X11 session is used, kill self
169     if (tlm_config_get_boolean (priv->config,
170                                 TLM_CONFIG_GENERAL,
171                                 TLM_CONFIG_GENERAL_X11_SESSION,
172                                 FALSE)) {
173         DBG ("X11 session termination");
174         if (kill (0, SIGTERM))
175             WARN ("Failed to send TERM signal to process tree");
176         return;
177     }
178
179     // Auto re-login, if the auto-login option is set
180     if (tlm_config_get_boolean (priv->config,
181                                 TLM_CONFIG_GENERAL,
182                                 TLM_CONFIG_GENERAL_AUTO_LOGIN,
183                                 TRUE) ||
184                                 seat->priv->next_user) {
185         DBG ("auto re-login with '%s'", seat->priv->next_user);
186
187         tlm_seat_create_session (seat,
188                 seat->priv->next_service,
189                 seat->priv->next_user,
190                 seat->priv->next_password,
191                 seat->priv->next_environment);
192         _reset_next (priv);
193     }
194 }
195
196 static void
197 _handle_error (
198         TlmSeat *self,
199         GError *error,
200         gpointer user_data)
201 {
202     g_return_if_fail (self && TLM_IS_SEAT (self));
203
204     DBG ("Error : %d:%s", error->code, error->message);
205     g_signal_emit (self, signals[SIG_SESSION_ERROR],  0, error->code);
206
207     if ((error->code == TLM_ERROR_PAM_AUTH_FAILURE ||
208         error->code == TLM_ERROR_SESSION_CREATION_FAILURE ||
209         error->code == TLM_ERROR_SESSION_TERMINATION_FAILURE)
210         && (!(self->priv->manager_stop))) {
211         DBG ("Destroy the session in case of creation/termination failure");
212         _close_active_session (self);
213         g_clear_object (&self->priv->dbus_observer);
214     }
215 }
216
217 static void
218 _disconnect_session_signals (
219         TlmSeat *seat)
220 {
221     TlmSeatPrivate *priv = TLM_SEAT_PRIV (seat);
222     if (!priv->session) return;
223     DBG ("seat %p session %p", seat, priv->session);
224
225     g_signal_handlers_disconnect_by_func (G_OBJECT (priv->session),
226             _handle_session_created, seat);
227     g_signal_handlers_disconnect_by_func (G_OBJECT (priv->session),
228             _handle_session_terminated, seat);
229     g_signal_handlers_disconnect_by_func (G_OBJECT (priv->session),
230             _handle_error, seat);
231 }
232
233 static void
234 _connect_session_signals (
235         TlmSeat *seat)
236 {
237     TlmSeatPrivate *priv = TLM_SEAT_PRIV (seat);
238     DBG ("seat %p", seat);
239     /* Connect session signals to handlers */
240     g_signal_connect_swapped (priv->session, "session-created",
241             G_CALLBACK (_handle_session_created), seat);
242     g_signal_connect_swapped (priv->session, "session-terminated",
243             G_CALLBACK(_handle_session_terminated), seat);
244     g_signal_connect_swapped (priv->session, "session-error",
245             G_CALLBACK(_handle_error), seat);
246 }
247
248 static gboolean
249 _create_dbus_observer (
250         TlmSeat *seat,
251         const gchar *username)
252 {
253     gchar *address = NULL;
254     uid_t uid = 0;
255
256     if (!username) return FALSE;
257
258     uid = tlm_user_get_uid (username);
259     if (uid == -1) return FALSE;
260
261     address = g_strdup_printf ("unix:path=%s/%s-%d", TLM_DBUS_SOCKET_PATH,
262             seat->priv->id, uid);
263     seat->priv->dbus_observer = TLM_DBUS_OBSERVER (tlm_dbus_observer_new (
264             NULL, seat, address, uid,
265             DBUS_OBSERVER_ENABLE_LOGOUT_USER |
266             DBUS_OBSERVER_ENABLE_SWITCH_USER));
267     g_free (address);
268     DBG ("created dbus obs: %p", seat->priv->dbus_observer);
269     return (seat->priv->dbus_observer != NULL);
270 }
271
272 static void
273 tlm_seat_dispose (GObject *self)
274 {
275     TlmSeat *seat = TLM_SEAT(self);
276
277     DBG("disposing seat: %s", seat->priv->id);
278
279     g_clear_object (&seat->priv->dbus_observer);
280     g_clear_object (&seat->priv->prev_dbus_observer);
281
282     _disconnect_session_signals (seat);
283     if (seat->priv->session)
284         g_clear_object (&seat->priv->session);
285     if (seat->priv->config) {
286         g_object_unref (seat->priv->config);
287         seat->priv->config = NULL;
288     }
289
290     G_OBJECT_CLASS (tlm_seat_parent_class)->dispose (self);
291 }
292
293 static void
294 tlm_seat_finalize (GObject *self)
295 {
296     TlmSeat *seat = TLM_SEAT(self);
297     TlmSeatPrivate *priv = TLM_SEAT_PRIV(seat);
298
299     g_clear_string (&priv->id);
300     g_clear_string (&priv->default_user);
301     g_clear_string (&priv->path);
302
303     _reset_next (priv);
304
305     G_OBJECT_CLASS (tlm_seat_parent_class)->finalize (self);
306 }
307
308 static void
309 _seat_set_property (GObject *obj,
310                     guint property_id,
311                     const GValue *value,
312                     GParamSpec *pspec)
313 {
314     TlmSeat *seat = TLM_SEAT(obj);
315     TlmSeatPrivate *priv = TLM_SEAT_PRIV(seat);
316
317     switch (property_id) {
318         case PROP_CONFIG:
319             priv->config = g_value_dup_object (value);
320             break;
321         case PROP_ID:
322             priv->id = g_value_dup_string (value);
323             break;
324         case PROP_PATH:
325             priv->path = g_value_dup_string (value);
326             break;
327         default:
328             G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
329     }
330 }
331
332 static void
333 _seat_get_property (GObject *obj,
334                     guint property_id,
335                     GValue *value,
336                     GParamSpec *pspec)
337 {
338     TlmSeat *seat = TLM_SEAT(obj);
339     TlmSeatPrivate *priv = TLM_SEAT_PRIV(seat);
340
341     switch (property_id) {
342         case PROP_CONFIG:
343             g_value_set_object (value, priv->config);
344             break;
345         case PROP_ID:
346             g_value_set_string (value, priv->id);
347             break;
348         case PROP_PATH:
349             g_value_set_string (value, priv->path);
350             break;
351         default:
352             G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
353     }
354 }
355
356 static void
357 tlm_seat_class_init (TlmSeatClass *klass)
358 {
359     GObjectClass *g_klass = G_OBJECT_CLASS (klass);
360
361     g_type_class_add_private (klass, sizeof (TlmSeatPrivate));
362
363     g_klass->dispose = tlm_seat_dispose ;
364     g_klass->finalize = tlm_seat_finalize;
365     g_klass->set_property = _seat_set_property;
366     g_klass->get_property = _seat_get_property;
367
368     pspecs[PROP_CONFIG] =
369         g_param_spec_object ("config",
370                              "config object",
371                              "Configuration object",
372                              TLM_TYPE_CONFIG,
373                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|
374                              G_PARAM_STATIC_STRINGS);
375     pspecs[PROP_ID] =
376         g_param_spec_string ("id",
377                              "seat id",
378                              "Seat Id",
379                              NULL,
380                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|
381                              G_PARAM_STATIC_STRINGS);
382     pspecs[PROP_PATH] =
383         g_param_spec_string ("path",
384                              "object path",
385                              "Seat Object path at logind",
386                              NULL,
387                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|
388                              G_PARAM_STATIC_STRINGS);
389     g_object_class_install_properties (g_klass, N_PROPERTIES, pspecs);
390
391     signals[SIG_PREPARE_USER_LOGIN] = g_signal_new ("prepare-user-login",
392                                               TLM_TYPE_SEAT,
393                                               G_SIGNAL_RUN_LAST,
394                                               0,
395                                               NULL,
396                                               NULL,
397                                               NULL,
398                                               G_TYPE_NONE,
399                                               1,
400                                               G_TYPE_STRING);
401     signals[SIG_PREPARE_USER_LOGOUT] = g_signal_new ("prepare-user-logout",
402                                               TLM_TYPE_SEAT,
403                                               G_SIGNAL_RUN_LAST,
404                                               0,
405                                               NULL,
406                                               NULL,
407                                               NULL,
408                                               G_TYPE_NONE,
409                                               1,
410                                               G_TYPE_STRING);
411     signals[SIG_SESSION_CREATED] = g_signal_new ("session-created",
412                                                     TLM_TYPE_SEAT,
413                                                     G_SIGNAL_RUN_LAST,
414                                                     0,
415                                                     NULL,
416                                                     NULL,
417                                                     NULL,
418                                                     G_TYPE_NONE,
419                                                     1,
420                                                     G_TYPE_STRING);
421     signals[SIG_SESSION_TERMINATED] = g_signal_new ("session-terminated",
422                                                     TLM_TYPE_SEAT,
423                                                     G_SIGNAL_RUN_LAST,
424                                                     0,
425                                                     NULL,
426                                                     NULL,
427                                                     NULL,
428                                                     G_TYPE_BOOLEAN,
429                                                     1,
430                                                     G_TYPE_STRING);
431     signals[SIG_SESSION_ERROR] = g_signal_new ("session-error",
432                                                     TLM_TYPE_SEAT,
433                                                     G_SIGNAL_RUN_LAST,
434                                                     0,
435                                                     NULL,
436                                                     NULL,
437                                                     NULL,
438                                                     G_TYPE_NONE,
439                                                     1,
440                                                     G_TYPE_UINT);
441 }
442
443 static void
444 tlm_seat_init (TlmSeat *seat)
445 {
446     TlmSeatPrivate *priv = TLM_SEAT_PRIV (seat);
447
448     priv->id = priv->path = priv->default_user = NULL;
449     priv->dbus_observer = priv->prev_dbus_observer = NULL;
450     priv->default_active = FALSE;
451     priv->manager_stop = FALSE;
452     seat->priv = priv;
453 }
454
455 const gchar *
456 tlm_seat_get_id (TlmSeat *seat)
457 {
458     g_return_val_if_fail (seat && TLM_IS_SEAT (seat), NULL);
459
460     return (const gchar*) seat->priv->id;
461 }
462
463 gchar *
464 tlm_seat_get_occupying_username (TlmSeat *seat) {
465     TlmSeatPrivate *priv = TLM_SEAT_PRIV (seat);
466     if (!priv->session) return NULL;
467
468     TlmSessionRemote *sr = priv->session;
469     gchar *username = NULL;
470
471     g_object_get(G_OBJECT(sr), "username", &username, NULL);
472
473     return username;
474 }
475
476 gboolean
477 tlm_seat_switch_user (TlmSeat *seat,
478                       const gchar *service,
479                       const gchar *username,
480                       const gchar *password,
481                       GHashTable *environment)
482 {
483     DBG("run tlm_seat_switch_user()");
484     g_return_val_if_fail (seat && TLM_IS_SEAT(seat), FALSE);
485
486     TlmSeatPrivate *priv = TLM_SEAT_PRIV (seat);
487
488     // If username & its password is not authenticated, immediately return FALSE
489     // so that current session is not terminated.
490     if (!tlm_authenticate_user (priv->config, username, password)) {
491         WARN("fail to tlm_authenticate_user");
492         return FALSE;
493     }
494
495     if (!priv->session) {
496         DBG("No live session, so just create session.");
497         return tlm_seat_create_session (seat, service, username, password,
498                 environment);
499     }
500
501     DBG("Store service/user/password/env as seat->priv->next_*, and terminate current session");
502     _reset_next (priv);
503     priv->next_service = g_strdup (service);
504     priv->next_user = g_strdup (username);
505     priv->next_password = g_strdup (password);
506     priv->next_environment = g_hash_table_ref (environment);
507
508     return tlm_seat_terminate_session (seat, FALSE);
509 }
510
511 static gchar *
512 _build_user_name (const gchar *template, const gchar *seat_id)
513 {
514     int seat_num = 0;
515     const char *pptr;
516     gchar *out;
517     GString *str;
518
519     if (strncmp (seat_id, "seat", 4) == 0)
520         seat_num = atoi (seat_id + 4);
521     else
522         WARN ("Unrecognized seat id format");
523     pptr = template;
524     str = g_string_sized_new (16);
525     while (*pptr != '\0') {
526         if (*pptr == '%') {
527             pptr++;
528             switch (*pptr) {
529                 case 'S':
530                     g_string_append_printf (str, "%d", seat_num);
531                     break;
532                 case 'I':
533                     g_string_append (str, seat_id);
534                     break;
535                 default:
536                     ;
537             }
538         } else {
539             g_string_append_c (str, *pptr);
540         }
541         pptr++;
542     }
543     out = g_string_free (str, FALSE);
544     return out;
545 }
546
547 static gboolean
548 _delayed_session (gpointer user_data)
549 {
550     DelayClosure *delay_closure = (DelayClosure *) user_data;
551
552     DBG ("delayed relogin for closure %p", delay_closure);
553     g_return_val_if_fail (user_data, G_SOURCE_REMOVE);
554
555     DBG ("delayed relogin for seat=%s, service=%s, user=%s",
556          delay_closure->seat->priv->id,
557          delay_closure->service,
558          delay_closure->username);
559     tlm_seat_create_session (delay_closure->seat,
560                              delay_closure->service,
561                              delay_closure->username,
562                              delay_closure->password,
563                              delay_closure->environment);
564     g_object_unref (delay_closure->seat);
565     g_free (delay_closure->service);
566     g_free (delay_closure->username);
567     g_free (delay_closure->password);
568     if (delay_closure->environment)
569         g_hash_table_unref (delay_closure->environment);
570     g_slice_free (DelayClosure, delay_closure);
571     return G_SOURCE_REMOVE;
572 }
573
574 gboolean
575 _find_user_session(const gchar *username)
576 {
577     if (!username) return FALSE;
578
579     uid_t uid = tlm_user_get_uid (username);
580     if (uid == -1) return FALSE;
581
582     const gchar *run_path = tzplatform_getenv(TZ_SYS_RUN);
583     const gchar *sub_path = "/systemd/users/";
584     size_t len = strlen(run_path) + strlen(sub_path) + 6;
585
586     gboolean result = FALSE;
587     gchar *filename = malloc(len);
588
589     if (filename) {
590         g_snprintf(filename, len, "%s%s%d", run_path, sub_path, uid);
591         DBG ("find user runtime dir: %s", filename);
592         if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
593             WARN("Session was not ended yet");
594             result = TRUE;
595         }
596
597         free(filename);
598     }
599
600     return result;
601
602 }
603
604 gboolean
605 _register_delayed_session(TlmSeat *seat,
606                          const gchar *service,
607                          const gchar *username,
608                          const gchar *password,
609                          GHashTable *environment,
610                          guint timeout_sec)
611 {
612     WARN ("relogins spinning too fast, delay...");
613     DelayClosure *delay_closure = g_slice_new0 (DelayClosure);
614     if (!delay_closure) {
615       CRITICAL("g_slice_new0 memory allication failure");
616       return FALSE;
617     }
618     delay_closure->seat = g_object_ref (seat);
619     delay_closure->service = g_strdup (service);
620     delay_closure->username = g_strdup (username);
621     delay_closure->password = g_strdup (password);
622     if (environment)
623         delay_closure->environment = g_hash_table_ref (environment);
624     g_timeout_add_seconds (timeout_sec, _delayed_session, delay_closure);
625
626     return TRUE;
627
628 }
629
630 gboolean
631 tlm_seat_create_session (TlmSeat *seat,
632                          const gchar *service,
633                          const gchar *username,
634                          const gchar *password,
635                          GHashTable *environment)
636 {
637     g_return_val_if_fail (seat && TLM_IS_SEAT(seat), FALSE);
638     TlmSeatPrivate *priv = TLM_SEAT_PRIV (seat);
639
640     // Ignore creating session if there is an existing session already
641     if (priv->session != NULL) {
642         WARN("Session already exists on this seat(%s)", priv->id);
643         g_signal_emit (seat, signals[SIG_SESSION_ERROR],  0,
644                 TLM_ERROR_SESSION_ALREADY_EXISTS);
645         return FALSE;
646     }
647
648     // Check same user's session was existed, or not.
649     // If TRUE, run _delayed_session. (try again after 3sec)
650     if (_find_user_session(username)) {
651         return _register_delayed_session(seat, service, username, password, environment, 3);
652     }
653
654     // Prevent short-delay relogin.
655     // If the login delay is too fast (<1s), run _delayed_session()
656     if (g_get_monotonic_time () - priv->prev_time < 1000000) {
657         DBG ("short time relogin");
658         priv->prev_time = g_get_monotonic_time ();
659         priv->prev_count++;
660         if (priv->prev_count > 3) {
661             return _register_delayed_session(seat, service, username, password, environment, 10);
662         }
663     } else {
664         priv->prev_time = g_get_monotonic_time ();
665         priv->prev_count = 1;
666     }
667
668     // Check for function arguments
669     // service: if NULL, get default service
670     if (!service) {
671         DBG ("PAM service not defined, looking up configuration");
672         service = tlm_config_get_string (priv->config,
673                                          priv->id,
674                                          username ? TLM_CONFIG_GENERAL_PAM_SERVICE : TLM_CONFIG_GENERAL_DEFAULT_PAM_SERVICE);
675         if (!service)
676             service = tlm_config_get_string (priv->config,
677                                              TLM_CONFIG_GENERAL,
678                                              username ? TLM_CONFIG_GENERAL_PAM_SERVICE : TLM_CONFIG_GENERAL_DEFAULT_PAM_SERVICE);
679         if (!service)
680             service = username ? "tlm-login" : "tlm-default-login";
681     }
682     DBG ("using PAM service %s for seat %s", service, priv->id);
683
684     // username: if NULL, get default user
685     if (!username) {
686         if (!priv->default_user) {
687             const gchar *name_tmpl =
688                     tlm_config_get_string_default (priv->config,
689                             priv->id,
690                             TLM_CONFIG_GENERAL_DEFAULT_USER,
691                             "guest");
692             if (!name_tmpl)
693                 name_tmpl = tlm_config_get_string_default (priv->config,
694                         TLM_CONFIG_GENERAL,
695                         TLM_CONFIG_GENERAL_DEFAULT_USER,
696                         "guest");
697             if (name_tmpl)
698                 priv->default_user = _build_user_name (name_tmpl, priv->id);
699         }
700         if (priv->default_user) {
701             priv->default_active = TRUE;
702             g_signal_emit (seat,
703                            signals[SIG_PREPARE_USER_LOGIN],
704                            0,
705                            priv->default_user);
706         }
707     }
708
709     // Create a session_remote object (It creates actual remote session process)
710     priv->session = tlm_session_remote_new (priv->config,
711             priv->id,
712             service,
713             priv->default_active ? priv->default_user : username);
714     if (!priv->session) {
715
716         g_signal_emit (seat, signals[SIG_SESSION_ERROR], 0,
717                 TLM_ERROR_SESSION_CREATION_FAILURE);
718         return FALSE;
719     }
720
721     /*It is needed to handle switch user case which completes after new session
722      *is created */
723     // TODO: process this prev_dbus_observer somewhere!
724     seat->priv->prev_dbus_observer = seat->priv->dbus_observer;
725     seat->priv->dbus_observer = NULL;
726     if (!_create_dbus_observer (seat,
727             priv->default_active ? priv->default_user : username)) {
728         if (priv->session) {
729             DBG("Clear session_remote object");
730             g_clear_object (&priv->session);
731         }
732         g_signal_emit (seat, signals[SIG_SESSION_ERROR],  0,
733                 TLM_ERROR_DBUS_SERVER_START_FAILURE);
734         return FALSE;
735     }
736
737     _connect_session_signals (seat);
738     tlm_session_remote_create (priv->session, password, environment);
739     return TRUE;
740 }
741
742 gboolean
743 tlm_seat_terminate_session (TlmSeat *seat, gboolean stop)
744 {
745     g_return_val_if_fail (seat && TLM_IS_SEAT(seat), FALSE);
746     g_return_val_if_fail (seat->priv, FALSE);
747
748     if (seat->priv->default_active) {
749         seat->priv->default_active = FALSE;
750         g_signal_emit (seat,
751                 signals[SIG_PREPARE_USER_LOGOUT],
752                 0,
753                 seat->priv->default_user);
754     }
755
756     if (!(seat->priv->manager_stop))
757         seat->priv->manager_stop = stop;
758
759     if (!seat->priv->session ||
760         !tlm_session_remote_terminate (seat->priv->session)) {
761         WARN ("No active session to terminate");
762         g_signal_emit (seat, signals[SIG_SESSION_ERROR], 0,
763                 TLM_ERROR_SESSION_NOT_VALID);
764         return FALSE;
765     }
766     return TRUE;
767 }
768
769 TlmSeat *
770 tlm_seat_new (TlmConfig *config,
771               const gchar *id,
772               const gchar *path)
773 {
774     TlmSeat *seat = g_object_new (TLM_TYPE_SEAT,
775                          "config", config,
776                          "id", id,
777                          "path", path,
778                          NULL);
779     return seat;
780 }
781