From d563d910b5e4b7287038dbfd0eacea0fc9a8767c Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Thu, 17 Mar 2016 17:08:38 +0300 Subject: [PATCH 2/2] Use the ConsoleKit database for at_console support This patch allows dbus to use the consolekit database to lookup the user and determine if one or more sessions is local. Failing to find the user is local, it will continute to fallback to checking the console auth dir. --- cmake/CMakeLists.txt | 3 ++ cmake/config.h.cmake | 1 + configure.ac | 11 ++++++ dbus/Makefile.am | 2 + dbus/dbus-sysdeps-util-unix.c | 92 ++++++++++++++++++++++++++++++++++++++++++- dbus/dbus-sysdeps.h | 1 + dbus/dbus-userdb-util.c | 2 +- 7 files changed, 110 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5bb4240..3ee02c6 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -446,8 +446,10 @@ set (DBUS_SYSTEM_PID_FILE ${DBUS_LOCALSTATEDIR}/run/dbus/pid) if (WIN32) set (DBUS_CONSOLE_AUTH_DIR "") + set (DBUS_CONSOLEKIT_DB "") else (WIN32) set (DBUS_CONSOLE_AUTH_DIR "/var/run/console/") + set (DBUS_CONSOLEKIT_DB "/var/run/ConsoleKit/database") endif (WIN32) # This won't work on Windows. It's not meant to - the system bus is @@ -601,6 +603,7 @@ message(" System bus address: ${DBUS_SYSTEM_BUS_DEFAULT_ADDRESS} " message(" System bus PID file: ${DBUS_SYSTEM_PID_FILE} ") message(" Session bus socket dir: ${DBUS_SESSION_SOCKET_DIR} ") message(" Console auth dir: ${DBUS_CONSOLE_AUTH_DIR} ") +message(" ConsoleKit database: ${DBUS_CONSOLEKIT_DB} ") message(" System bus user: ${DBUS_USER} ") message(" 'make check' socket dir: ${TEST_SOCKET_DIR} ") endif (WIN32) diff --git a/cmake/config.h.cmake b/cmake/config.h.cmake index c498362..d5ce140 100644 --- a/cmake/config.h.cmake +++ b/cmake/config.h.cmake @@ -15,6 +15,7 @@ #cmakedefine HAVE_GNUC_VARARGS 1 #cmakedefine DBUS_CONSOLE_AUTH_DIR "@DBUS_CONSOLE_AUTH_DIR@" +#cmakedefine DBUS_CONSOLEKIT_DB "@DBUS_CONSOLEKIT_DB@" #cmakedefine DBUS_DATADIR "@DBUS_DATADIR@" #cmakedefine DBUS_BINDIR "@DBUS_BINDIR@" #cmakedefine DBUS_PREFIX "@DBUS_PREFIX@" diff --git a/configure.ac b/configure.ac index 1d08030..c569d01 100644 --- a/configure.ac +++ b/configure.ac @@ -1595,6 +1595,16 @@ fi AC_SUBST(DBUS_CONSOLE_AUTH_DIR) AC_DEFINE_UNQUOTED(DBUS_CONSOLE_AUTH_DIR, "$DBUS_CONSOLE_AUTH_DIR", [Directory to check for console ownerhip]) +#### Location of the ConsoleKit database for at_console support +if ! test -z "$with_consolekit_db"; then + DBUS_CONSOLEKIT_DB=$with_consolekit_db +else + DBUS_CONSOLEKIT_DB=/var/run/ConsoleKit/database +fi + +AC_SUBST(DBUS_CONSOLEKIT_DB) +AC_DEFINE_UNQUOTED(DBUS_CONSOLEKIT_DB, "$DBUS_CONSOLEKIT_DB", [Location of the ConsoleKit database for at_console support]) + #### File to check for console ownership if test x$have_console_owner_file = xyes; then if ! test -z "$with_console_owner_file"; then @@ -1918,6 +1928,7 @@ echo " Session bus listens on: ${DBUS_SESSION_BUS_LISTEN_ADDRESS} Session clients connect to: ${DBUS_SESSION_BUS_CONNECT_ADDRESS} Console auth dir: ${DBUS_CONSOLE_AUTH_DIR} + ConsoleKit database: ${DBUS_CONSOLEKIT_DB} Console owner file: ${have_console_owner_file} Console owner file path: ${DBUS_CONSOLE_OWNER_FILE} System bus user: ${DBUS_USER} diff --git a/dbus/Makefile.am b/dbus/Makefile.am index a7b3491..e1ea33c 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -117,6 +117,8 @@ DBUS_SHARED_arch_sources = \ $(NULL) DBUS_UTIL_arch_sources = \ + $(top_builddir)/bus/desktop-file.c \ + $(top_builddir)/bus/desktop-file.h \ dbus-sysdeps-util-unix.c \ dbus-userdb-util.c \ dbus-spawn.c diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 1f9ddb9..abd76dd 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -29,6 +29,7 @@ #include "dbus-pipe.h" #include "dbus-protocol.h" #include "dbus-string.h" +#include "bus/desktop-file.h" #define DBUS_USERDB_INCLUDES_PRIVATE 1 #include "dbus-userdb.h" #include "dbus-test.h" @@ -624,6 +625,59 @@ _dbus_set_signal_handler (int sig, sigaction (sig, &act, NULL); } +static dbus_bool_t +_dbus_get_ck_user_is_local (BusDesktopFile *file, + dbus_uid_t uid, + DBusError *error) +{ + dbus_bool_t is_local; + DBusString user_group; + char *local_str; + + is_local = FALSE; + local_str = NULL; + + if (!_dbus_string_init (&user_group)) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + /* Create the User group to look into */ + if (!_dbus_string_append_printf (&user_group, "User %lu", uid)) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + if (!bus_desktop_file_get_string (file, + _dbus_string_get_const_data(&user_group), + "is_local", + &local_str, + error)) + { + /* If there's no User section then we're using an older version + * of ConsoleKit, ignore the error + */ + if (dbus_error_is_set (error)) + { + dbus_error_free (error); + } + } + else + { + if (local_str != NULL) + { + is_local = (strcmp (local_str, "true") == 0); + free (local_str); + } + } + + _dbus_string_free (&user_group); + + return is_local; +} + /** Checks if a file exists * * @param file full path to the file @@ -638,24 +692,60 @@ _dbus_file_exists (const char *file) /** Checks if user is at the console * * @param username user to check +* @param uid of user to check * @param error return location for errors -* @returns #TRUE is the user is at the consolei and there are no errors +* @returns #TRUE is the user is at the console and there are no errors */ dbus_bool_t _dbus_user_at_console (const char *username, + dbus_uid_t uid, DBusError *error) { + DBusString database; DBusString u, f; + BusDesktopFile *file; dbus_bool_t result; result = FALSE; + if (!_dbus_string_init (&f)) { _DBUS_SET_OOM (error); return FALSE; } + _dbus_string_init_const (&database, DBUS_CONSOLEKIT_DB); + + /* First, attempt to check if the user is local in the CK db. */ + if (_dbus_file_exists (DBUS_CONSOLEKIT_DB)) + { + file = bus_configuration_file_load (&database, FALSE, error); + + if (file != NULL) + { + if (_dbus_get_ck_user_is_local (file, uid, error)) + { + bus_desktop_file_free (file); + return TRUE; + } + + bus_desktop_file_free (file); + } + + /* If we encountered an error loading the ck database or ran into + * an OOM checking for is local, report that now + */ + if (dbus_error_is_set (error)) + { + return FALSE; + } + } + + /* If we got here, either we aren't using ConsoleKit2, or we're not using + * a new enough version, or the user isn't local. Whatever the reason, it + * won't hurt to fallback to trying the pam console fallback. + */ if (!_dbus_string_append (&f, DBUS_CONSOLE_AUTH_DIR)) { _DBUS_SET_OOM (error); diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index c832b3f..002450e 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -546,6 +546,7 @@ void _dbus_set_signal_handler (int sig, DBusSignalHandler handler); dbus_bool_t _dbus_user_at_console (const char *username, + dbus_uid_t uid, DBusError *error); void _dbus_init_system_log (dbus_bool_t is_daemon); diff --git a/dbus/dbus-userdb-util.c b/dbus/dbus-userdb-util.c index 888a23e..ecfd217 100644 --- a/dbus/dbus-userdb-util.c +++ b/dbus/dbus-userdb-util.c @@ -128,7 +128,7 @@ _dbus_is_console_user (dbus_uid_t uid, return FALSE; } - result = _dbus_user_at_console (info->username, error); + result = _dbus_user_at_console (info->username, uid, error); _dbus_user_database_unlock_system (); -- 2.7.3