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