Commit ec843a21 authored by Victor Toso's avatar Victor Toso

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: 's avatarPavel Grunt <pgrunt@redhat.com>
parent 49c421a8
......@@ -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)
......@@ -111,6 +118,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)
{
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment