1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of tlm (Tiny Login Manager)
6 * Copyright (C) 2014 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@gmail.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
35 #include <glib-unix.h>
36 #include <sys/types.h>
39 #include "common/dbus/tlm-dbus.h"
40 #include "common/tlm-log.h"
41 #include "common/tlm-config.h"
42 #include "common/dbus/tlm-dbus-login-gen.h"
43 #include "common/tlm-utils.h"
44 #include "common/dbus/tlm-dbus-utils.h"
46 static gchar *exe_name = 0;
47 static GPid daemon_pid = 0;
49 static GMainLoop *main_loop = NULL;
55 g_main_loop_quit (main_loop);
62 if (main_loop == NULL) {
63 main_loop = g_main_loop_new (NULL, FALSE);
70 DBG ("Programe name : %s\n", exe_name);
73 /* start daemon maually */
75 gchar *test_daemon_path = g_build_filename (g_getenv("TLM_BIN_DIR"),
77 fail_if (test_daemon_path == NULL, "No UM daemon path found");
79 argv[0] = test_daemon_path;
81 g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
83 g_free (test_daemon_path);
84 fail_if (error != NULL, "Failed to span daemon : %s",
85 error ? error->message : "");
86 sleep (5); /* 5 seconds */
88 DBG ("Daemon PID = %d\n", daemon_pid);
92 _teardown_daemon (void)
94 if (daemon_pid) kill (daemon_pid, SIGTERM);
98 _get_root_socket_bus_connection (
102 g_snprintf (address, 127, TLM_DBUS_ROOT_SOCKET_ADDRESS);
103 return g_dbus_connection_new_for_address_sync (address,
104 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, error);
108 _get_bus_connection (
109 const gchar *seat_id,
112 uid_t ui_user_id = getuid ();
114 if (ui_user_id == 0) {
115 return _get_root_socket_bus_connection (error);
118 /* get dbus connection for specific user only */
120 g_snprintf (address, 127, "unix:path=%s/%s-%d", TLM_DBUS_SOCKET_PATH,
121 seat_id, ui_user_id);
122 return g_dbus_connection_new_for_address_sync (address,
123 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, error);
128 GDBusConnection *connection,
131 return tlm_dbus_login_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
132 NULL, TLM_LOGIN_OBJECTPATH, NULL, error);
137 _get_session_property (
139 const gchar *object_path,
140 const gchar *prop_key)
142 GError *error = NULL;
143 GVariant *result = NULL;
144 GVariant *prop_value = NULL;
146 result = g_dbus_connection_call_sync (
147 g_dbus_proxy_get_connection (proxy),
148 g_dbus_proxy_get_name (proxy),
150 "org.freedesktop.DBus.Properties",
152 g_variant_new ("(s)", "org.freedesktop.login1.Session"),
153 G_VARIANT_TYPE ("(a{sv})"),
154 G_DBUS_CALL_FLAGS_NONE,
159 DBG ("Failed with error %d:%s", error->code, error->message);
160 g_error_free (error);
165 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(a{sv})"))) {
166 GVariantIter *iter = NULL;
167 GVariant *item = NULL;
168 g_variant_get (result, "(a{sv})", &iter);
169 while ((item = g_variant_iter_next_value (iter))) {
172 g_variant_get (item, "{sv}", &key, &value);
173 if (g_strcmp0 (key, prop_key) == 0) {
175 g_free (key); key = NULL;
178 g_free (key); key = NULL;
179 g_variant_unref (value); value = NULL;
182 g_variant_unref (result);
188 const gchar *prop_key)
190 GError *error = NULL;
191 GDBusProxy *proxy = NULL;
192 GVariant *res = NULL;
193 GVariant *prop_value = NULL;
195 GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL,
197 if (error) goto _finished;
199 proxy = g_dbus_proxy_new_sync (connection,
200 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
201 "org.freedesktop.login1", //destintation
202 "/org/freedesktop/login1", //path
203 "org.freedesktop.login1.Manager", //interface
205 if (error) goto _finished;
207 res = g_dbus_proxy_call_sync (proxy, "GetSessionByPID",
208 g_variant_new ("(u)", getpid()), G_DBUS_CALL_FLAGS_NONE, -1,
211 gchar *obj_path = NULL;
212 g_variant_get (res, "(o)", &obj_path);
213 prop_value = _get_session_property (proxy, obj_path, prop_key);
214 g_variant_unref (res); res = NULL;
220 DBG ("failed to listen for login events: %s", error->message);
221 g_error_free (error);
223 if (proxy) g_object_unref (proxy);
224 if (connection) g_object_unref (connection);
230 * Login object test cases
232 START_TEST (test_login_user)
235 GError *error = NULL;
236 GDBusConnection *connection = NULL;
237 TlmDbusLogin *login_object = NULL;
238 GHashTable *environ = NULL;
239 GVariant *venv = NULL;
240 GVariant *vseat = NULL;
243 vseat = _get_property ("Seat");
244 fail_if (vseat == NULL);
245 g_variant_get (vseat, "(so)", &seat, NULL);
246 g_variant_unref (vseat);
248 connection = _get_bus_connection (seat, &error);
249 fail_if (connection == NULL, "failed to get bus connection : %s",
250 error ? error->message : "(null)");
253 login_object = _get_login_object (connection, &error);
254 fail_if (login_object == NULL, "failed to get login object: %s",
255 error ? error->message : "");
257 environ = g_hash_table_new_full ((GHashFunc)g_str_hash,
258 (GEqualFunc)g_str_equal,
259 (GDestroyNotify)g_free,
260 (GDestroyNotify)g_free);
261 venv = tlm_dbus_utils_hash_table_to_variant (environ);
263 g_hash_table_unref (environ);
265 fail_if (tlm_dbus_login_call_login_user_sync (login_object,
266 "seat0", "test01234567", "test1", venv, NULL, &error) == TRUE);
269 g_error_free (error);
272 g_object_unref (login_object);
273 g_object_unref (connection);
277 Suite* daemon_suite (void)
281 Suite *s = suite_create ("Tlm daemon");
283 tc = tcase_create ("Daemon tests");
284 tcase_set_timeout(tc, 15);
285 tcase_add_unchecked_fixture (tc, _setup_daemon, _teardown_daemon);
286 tcase_add_checked_fixture (tc, _create_mainloop, _stop_mainloop);
288 tcase_add_test (tc, test_login_user);
289 suite_add_tcase (s, tc);
294 int main (int argc, char *argv[])
300 #if !GLIB_CHECK_VERSION (2, 36, 0)
307 sr = srunner_create(s);
309 srunner_run_all(sr, CK_VERBOSE);
311 number_failed = srunner_ntests_failed(sr);
314 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;