#include <utmpx.h>
#include <sys/mman.h>
+#if HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
#include "configuration.h"
#include "session-child.h"
#include "session.h"
+#include "console-kit.h"
#include "login1.h"
+#include "log-file.h"
#include "privileges.h"
#include "x-authority.h"
#include "configuration.h"
updwtmp (wtmp_file, &u);
}
+#if HAVE_LIBAUDIT
+static void
+audit_event (int type, const gchar *username, uid_t uid, const gchar *remote_host_name, const gchar *tty, gboolean success)
+{
+ int auditfd, result;
+ const char *op = NULL;
+
+ auditfd = audit_open ();
+ if (auditfd < 0) {
+ g_printerr ("Error opening audit socket: %s\n", strerror (errno));
+ return;
+ }
+
+ if (type == AUDIT_USER_LOGIN)
+ op = "login";
+ else if (type == AUDIT_USER_LOGOUT)
+ op = "logout";
+ result = success == TRUE ? 1 : 0;
+
+ if (audit_log_acct_message (auditfd, type, NULL, op, username, uid, remote_host_name, NULL, tty, result) <= 0)
+ g_printerr ("Error writing audit message: %s\n", strerror (errno));
+
+ close (auditfd);
+}
+#endif
+
int
session_child_run (int argc, char **argv)
{
int i, version, fd, result;
gboolean auth_complete = TRUE;
User *user = NULL;
- gchar *log_filename, *log_backup_filename = NULL;
+ gchar *log_filename;
+ LogMode log_mode = LOG_MODE_BACKUP_AND_TRUNCATE;
gsize env_length;
gsize command_argc;
gchar **command_argv;
+ GVariantBuilder ck_parameters;
int return_code;
int authentication_result;
gchar *authentication_result_string;
gchar *xdisplay;
XAuthority *x_authority = NULL;
gchar *x_authority_filename;
- const gchar *login1_session = NULL;
+ GDBusConnection *bus;
+ const gchar *login1_session_id = NULL;
+ gchar *console_kit_cookie = NULL;
const gchar *locale_value;
gchar *locale_var;
static const gchar * const locale_var_names[] = {
+ "LC_PAPER",
+ "LC_NAME",
+ "LC_ADDRESS",
+ "LC_TELEPHONE",
+ "LC_MEASUREMENT",
+ "LC_IDENTIFICATION",
"LC_COLLATE",
"LC_CTYPE",
"LC_MONETARY",
gid_t gid;
uid_t uid;
const gchar *home_directory;
+ GError *error = NULL;
#if !defined(GLIB_VERSION_2_36)
g_type_init ();
ut.ut_type = USER_PROCESS;
ut.ut_pid = getpid ();
if (xdisplay)
- {
- strncpy (ut.ut_line, xdisplay, sizeof (ut.ut_line));
strncpy (ut.ut_id, xdisplay, sizeof (ut.ut_id));
- }
- else if (tty)
+ if (tty && g_str_has_prefix (tty, "/dev/"))
strncpy (ut.ut_line, tty + strlen ("/dev/"), sizeof (ut.ut_line));
strncpy (ut.ut_user, username, sizeof (ut.ut_user));
if (xdisplay)
ut.ut_tv.tv_usec = tv.tv_usec;
updwtmpx ("/var/log/btmp", &ut);
+
+#if HAVE_LIBAUDIT
+ audit_event (AUDIT_USER_LOGIN, username, -1, remote_host_name, tty, FALSE);
+#endif
}
/* Check account is valid */
/* Get the command to run (blocks) */
log_filename = read_string ();
+ if (version >= 3)
+ read_data (&log_mode, sizeof (log_mode));
if (version >= 1)
{
g_free (tty);
/* Redirect stderr to a log file */
if (log_filename)
{
- log_backup_filename = g_strdup_printf ("%s.old", log_filename);
if (g_path_is_absolute (log_filename))
{
- rename (log_filename, log_backup_filename);
- fd = open (log_filename, O_WRONLY | O_APPEND | O_CREAT, 0600);
+ fd = log_file_open (log_filename, log_mode);
dup2 (fd, STDERR_FILENO);
close (fd);
g_free (log_filename);
return EXIT_FAILURE;
}
+ /* Open a connection to the system bus for ConsoleKit - we must keep it open or CK will close the session */
+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (error)
+ g_printerr ("Unable to contact system bus: %s", error->message);
+ if (!bus)
+ {
+ pam_end (pam_handle, 0);
+ return EXIT_FAILURE;
+ }
+
/* Check what logind session we are, or fallback to ConsoleKit */
- login1_session = pam_getenv (pam_handle, "XDG_SESSION_ID");
- if (login1_session)
+ login1_session_id = pam_getenv (pam_handle, "XDG_SESSION_ID");
+ if (login1_session_id)
{
- write_string (login1_session);
- /* Write what was a ConsoleKit cookie */
+ write_string (login1_session_id);
if (version >= 2)
write_string (NULL);
}
else
{
+ g_variant_builder_init (&ck_parameters, G_VARIANT_TYPE ("(a(sv))"));
+ g_variant_builder_open (&ck_parameters, G_VARIANT_TYPE ("a(sv)"));
+ g_variant_builder_add (&ck_parameters, "(sv)", "unix-user", g_variant_new_int32 (user_get_uid (user)));
+ if (g_strcmp0 (pam_getenv (pam_handle, "XDG_SESSION_CLASS"), "greeter") == 0)
+ g_variant_builder_add (&ck_parameters, "(sv)", "session-type", g_variant_new_string ("LoginWindow"));
+ if (xdisplay)
+ {
+ g_variant_builder_add (&ck_parameters, "(sv)", "x11-display", g_variant_new_string (xdisplay));
+ if (tty)
+ g_variant_builder_add (&ck_parameters, "(sv)", "x11-display-device", g_variant_new_string (tty));
+ }
+ if (remote_host_name)
+ {
+ g_variant_builder_add (&ck_parameters, "(sv)", "is-local", g_variant_new_boolean (FALSE));
+ g_variant_builder_add (&ck_parameters, "(sv)", "remote-host-name", g_variant_new_string (remote_host_name));
+ }
+ else
+ g_variant_builder_add (&ck_parameters, "(sv)", "is-local", g_variant_new_boolean (TRUE));
+ console_kit_cookie = ck_open_session (&ck_parameters);
if (version >= 2)
write_string (NULL);
- /* Write what was a ConsoleKit cookie */
- write_string (NULL);
+ write_string (console_kit_cookie);
+ if (console_kit_cookie)
+ {
+ gchar *value;
+ gchar *runtime_dir;
+ value = g_strdup_printf ("XDG_SESSION_COOKIE=%s", console_kit_cookie);
+ pam_putenv (pam_handle, value);
+ g_free (value);
+
+ runtime_dir = ck_get_xdg_runtime_dir (console_kit_cookie);
+ if (runtime_dir)
+ {
+ gchar *value;
+ value = g_strdup_printf ("XDG_RUNTIME_DIR=%s", runtime_dir);
+ pam_putenv (pam_handle, value);
+ g_free (value);
+ g_free (runtime_dir);
+ }
+ }
}
/* Write X authority */
if (log_filename)
{
- rename (log_filename, log_backup_filename);
- fd = open (log_filename, O_WRONLY | O_APPEND | O_CREAT, 0600);
+ fd = log_file_open (log_filename, log_mode);
if (fd >= 0)
{
dup2 (fd, STDERR_FILENO);
}
}
+ /* Reset SIGPIPE handler so the child has default behaviour (we disabled it at LightDM start) */
+ signal (SIGPIPE, SIG_DFL);
+
/* Run the command */
execve (command_argv[0], command_argv, pam_getenvlist (pam_handle));
_exit (EXIT_FAILURE);
ut.ut_type = USER_PROCESS;
ut.ut_pid = child_pid;
if (xdisplay)
- {
- strncpy (ut.ut_line, xdisplay, sizeof (ut.ut_line));
strncpy (ut.ut_id, xdisplay, sizeof (ut.ut_id));
- }
- else if (tty)
+ if (tty && g_str_has_prefix (tty, "/dev/"))
strncpy (ut.ut_line, tty + strlen ("/dev/"), sizeof (ut.ut_line));
strncpy (ut.ut_user, username, sizeof (ut.ut_user));
if (xdisplay)
g_printerr ("Failed to write utmpx: %s\n", strerror (errno));
endutxent ();
updwtmpx ("/var/log/wtmp", &ut);
+
+#if HAVE_LIBAUDIT
+ audit_event (AUDIT_USER_LOGIN, username, uid, remote_host_name, tty, TRUE);
+#endif
}
waitpid (child_pid, &return_code, 0);
ut.ut_type = DEAD_PROCESS;
ut.ut_pid = child_pid;
if (xdisplay)
- {
- strncpy (ut.ut_line, xdisplay, sizeof (ut.ut_line));
strncpy (ut.ut_id, xdisplay, sizeof (ut.ut_id));
- }
- else if (tty)
+ if (tty && g_str_has_prefix (tty, "/dev/"))
strncpy (ut.ut_line, tty + strlen ("/dev/"), sizeof (ut.ut_line));
strncpy (ut.ut_user, username, sizeof (ut.ut_user));
if (xdisplay)
g_printerr ("Failed to write utmpx: %s\n", strerror (errno));
endutxent ();
updwtmpx ("/var/log/wtmp", &ut);
+
+#if HAVE_LIBAUDIT
+ audit_event (AUDIT_USER_LOGOUT, username, uid, remote_host_name, tty, TRUE);
+#endif
}
}
_exit (EXIT_FAILURE);
}
+ /* Close the Console Kit session */
+ if (console_kit_cookie)
+ ck_close_session (console_kit_cookie);
+
/* Close the session */
pam_close_session (pam_handle, 0);
/* Remove credentials */
- result = pam_setcred (pam_handle, PAM_DELETE_CRED);
+ pam_setcred (pam_handle, PAM_DELETE_CRED);
pam_end (pam_handle, 0);
pam_handle = NULL;