summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Toso <victortoso@redhat.com>2016-05-27 11:42:29 +0200
committerVictor Toso <victortoso@redhat.com>2016-06-03 11:13:33 +0200
commitec843a21b29d7fa21ba3393b84368bc2e39d3ce7 (patch)
tree14617c4c1c8b31e2f2efa670f57c70617ee8c604
parent49c421a82cebeeb47f268d57d30384e650734ae9 (diff)
systemd-login: check for LockedHint property
Property introduced in v230 of systemd. Systems that don't have up to date systemd-login will get the following log message: "Properties.Get failed (locked-hint) due Unknown property or interface." Resolves: rhbz#1323623 Acked-by: Pavel Grunt <pgrunt@redhat.com>
-rw-r--r--src/systemd-login.c108
1 files changed, 98 insertions, 10 deletions
diff --git a/src/systemd-login.c b/src/systemd-login.c
index fa59348..9719c0b 100644
--- a/src/systemd-login.c
+++ b/src/systemd-login.c
@@ -36,14 +36,21 @@ struct session_info {
char *match_session_signals;
} dbus;
gboolean session_is_locked;
+ gboolean session_locked_hint;
};
+#define LOGIND_INTERFACE "org.freedesktop.login1"
+
#define LOGIND_SESSION_INTERFACE "org.freedesktop.login1.Session"
-#define LOGIND_SESSION_OBJ_TEMPLATE "'/org/freedesktop/login1/session/_3%s'"
+#define LOGIND_SESSION_OBJ_TEMPLATE "/org/freedesktop/login1/session/_3%s"
+
+#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
#define SESSION_SIGNAL_LOCK "Lock"
#define SESSION_SIGNAL_UNLOCK "Unlock"
+#define SESSION_PROP_LOCKED_HINT "LockedHint"
+
/* dbus related */
static DBusConnection *si_dbus_get_system_bus(void)
{
@@ -91,8 +98,8 @@ static void si_dbus_match_rule_update(struct session_info *si)
si_dbus_match_remove(si);
si->dbus.match_session_signals =
- g_strdup_printf ("type='signal',interface='%s',path="
- LOGIND_SESSION_OBJ_TEMPLATE,
+ g_strdup_printf ("type='signal',interface='%s',path='"
+ LOGIND_SESSION_OBJ_TEMPLATE"'",
LOGIND_SESSION_INTERFACE,
si->session);
if (si->verbose)
@@ -112,6 +119,84 @@ static void si_dbus_match_rule_update(struct session_info *si)
}
static void
+si_dbus_read_properties(struct session_info *si)
+{
+ dbus_bool_t locked_hint, ret;
+ DBusMessageIter iter, iter_variant;
+ gint type;
+ DBusError error;
+ DBusMessage *message = NULL;
+ DBusMessage *reply = NULL;
+ gchar *session_object;
+ const gchar *interface, *property;
+
+ if (si->session == NULL)
+ return;
+
+ session_object = g_strdup_printf(LOGIND_SESSION_OBJ_TEMPLATE, si->session);
+ message = dbus_message_new_method_call(LOGIND_INTERFACE,
+ session_object,
+ DBUS_PROPERTIES_INTERFACE,
+ "Get");
+ g_free (session_object);
+ if (message == NULL) {
+ syslog(LOG_ERR, "Unable to create dbus message");
+ goto exit;
+ }
+
+ interface = LOGIND_SESSION_INTERFACE;
+ property = SESSION_PROP_LOCKED_HINT;
+ ret = dbus_message_append_args(message,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_STRING, &property,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ syslog(LOG_ERR, "Unable to request locked-hint");
+ goto exit;
+ }
+
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(si->dbus.system_connection,
+ message,
+ -1,
+ &error);
+ if (reply == NULL) {
+ if (dbus_error_is_set(&error)) {
+ syslog(LOG_ERR, "Properties.Get failed (locked-hint) due %s", error.message);
+ dbus_error_free(&error);
+ } else {
+ syslog(LOG_ERR, "Properties.Get failed (locked-hint)");
+ }
+ goto exit;
+ }
+
+ dbus_message_iter_init(reply, &iter);
+ type = dbus_message_iter_get_arg_type(&iter);
+ if (type != DBUS_TYPE_VARIANT) {
+ syslog(LOG_ERR, "expected a variant, got a '%c' instead", type);
+ goto exit;
+ }
+
+ dbus_message_iter_recurse(&iter, &iter_variant);
+ type = dbus_message_iter_get_arg_type(&iter_variant);
+ if (type != DBUS_TYPE_BOOLEAN) {
+ syslog(LOG_ERR, "expected a boolean, got a '%c' instead", type);
+ goto exit;
+ }
+ dbus_message_iter_get_basic(&iter_variant, &locked_hint);
+
+ si->session_locked_hint = (locked_hint) ? TRUE : FALSE;
+exit:
+ if (reply != NULL) {
+ dbus_message_unref(reply);
+ }
+
+ if (message != NULL) {
+ dbus_message_unref(message);
+ }
+}
+
+static void
si_dbus_read_signals(struct session_info *si)
{
DBusMessage *message = NULL;
@@ -220,16 +305,19 @@ char *session_info_session_for_pid(struct session_info *si, uint32_t pid)
gboolean session_info_session_is_locked(struct session_info *si)
{
- g_return_val_if_fail (si != NULL, FALSE);
+ gboolean locked;
- /* We could also rely on IdleHint property from Session which seems to work
- * well in rhel7 but it wasn't working well in my own system (F23). I'm
- * convinced for now that Lock/Unlock signals should be enough but that
- * means Lock/Unlock being done by logind. That might take a while.
- * Check: https://bugzilla.gnome.org/show_bug.cgi?id=764773 */
+ g_return_val_if_fail (si != NULL, FALSE);
si_dbus_read_signals(si);
- return si->session_is_locked;
+ si_dbus_read_properties(si);
+
+ locked = (si->session_is_locked || si->session_locked_hint);
+ if (si->verbose) {
+ syslog(LOG_DEBUG, "(systemd-login) session is locked: %s",
+ locked ? "yes" : "no");
+ }
+ return locked;
}
/* This function should only be called after session_info_get_active_session