diff options
author | Ray Strode <rstrode@redhat.com> | 2008-02-06 05:00:15 +0000 |
---|---|---|
committer | Ray Strode <halfline@src.gnome.org> | 2008-02-06 05:00:15 +0000 |
commit | f616d973837ec266c10d34404f859f66b717bfff (patch) | |
tree | df5d7ed5707c3e19635f97ab84fda54e2e30aff4 | |
parent | 46b6d03d4c191fc20c584529aec2574b39af044d (diff) | |
download | gdm-f616d973837ec266c10d34404f859f66b717bfff.tar.gz |
Add PAM auditing logic. Based on patch and feedback from Brian Cameron and
2008-02-05 Ray Strode <rstrode@redhat.com>
Add PAM auditing logic. Based on patch and feedback from
Brian Cameron and earlier code from Gary Winiger and
Steve Grubb.
* configure.ac: set HAVE_ADT and HAVE_LIBAUDIT as appropriate
for solaris and linux audit support, respectively.
* daemon/Makefile.am: add new auditing code to Makefile.
* daemon/gdm-session-auditor.[ch]: generic base class for doing
auditing.
* daemon/gdm-session-linux-auditor.[ch]: linux auditor subclass
* daemon/gdm-session-solaris-auditor.[ch]: solaris auditor
subclass
* daemon/gdm-session-worker.c (GdmSessionWorkerPrivate): track
auditor
(gdm_session_worker_update_username): inform audit code about
username changes
(gdm_session_worker_start_auditor): instantiate the auditor
(gdm_session_worker_stop_auditor): free the auditor
(gdm_session_worker_uninitialize_pam): inform audit code about
logout/login failure and then free the auditor
(_get_tty_for_pam): fix calling return more than once on solaris
(gdm_session_worker_initialize_pam): instantiate the auditor.
(gdm_session_worker_authorize_user): inform audit code about
password changes
(gdm_session_worker_accredit_user): inform audit code about
user getting credentials
(gdm_session_worker_open_user_session): inform audit code about
successful login
svn path=/trunk/; revision=5702
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | configure.ac | 25 | ||||
-rw-r--r-- | daemon/Makefile.am | 12 | ||||
-rw-r--r-- | daemon/gdm-session-auditor.c | 305 | ||||
-rw-r--r-- | daemon/gdm-session-auditor.h | 81 | ||||
-rw-r--r-- | daemon/gdm-session-linux-auditor.c | 162 | ||||
-rw-r--r-- | daemon/gdm-session-linux-auditor.h | 63 | ||||
-rw-r--r-- | daemon/gdm-session-solaris-auditor.c | 391 | ||||
-rw-r--r-- | daemon/gdm-session-solaris-auditor.h | 63 | ||||
-rw-r--r-- | daemon/gdm-session-worker.c | 62 |
10 files changed, 1192 insertions, 3 deletions
@@ -1,3 +1,34 @@ +2008-02-05 Ray Strode <rstrode@redhat.com> + + Add PAM auditing logic. Based on patch and feedback from + Brian Cameron and earlier code from Gary Winiger and + Steve Grubb. + + * configure.ac: set HAVE_ADT and HAVE_LIBAUDIT as appropriate + for solaris and linux audit support, respectively. + * daemon/Makefile.am: add new auditing code to Makefile. + * daemon/gdm-session-auditor.[ch]: generic base class for doing + auditing. + * daemon/gdm-session-linux-auditor.[ch]: linux auditor subclass + * daemon/gdm-session-solaris-auditor.[ch]: solaris auditor + subclass + * daemon/gdm-session-worker.c (GdmSessionWorkerPrivate): track + auditor + (gdm_session_worker_update_username): inform audit code about + username changes + (gdm_session_worker_start_auditor): instantiate the auditor + (gdm_session_worker_stop_auditor): free the auditor + (gdm_session_worker_uninitialize_pam): inform audit code about + logout/login failure and then free the auditor + (_get_tty_for_pam): fix calling return more than once on solaris + (gdm_session_worker_initialize_pam): instantiate the auditor. + (gdm_session_worker_authorize_user): inform audit code about + password changes + (gdm_session_worker_accredit_user): inform audit code about + user getting credentials + (gdm_session_worker_open_user_session): inform audit code about + successful login + 2008-02-05 William Jon McCann <jmccann@redhat.com> * data/session-setup.entries: diff --git a/configure.ac b/configure.ac index 3e01fad1..066890dd 100644 --- a/configure.ac +++ b/configure.ac @@ -995,11 +995,34 @@ adt_user_context = ADT_USER; if test ${check_sun_audit} = yes then AC_DEFINE(HAVE_ADT) - EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lbsm" + PAM_LIBS="$PAM_LIBS -lbsm" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi +AM_CONDITIONAL(HAVE_ADT, test x$check_sun_audit = xyes) + +# Check for Linux auditing API +# +AC_ARG_WITH(libaudit, + [ --with-libaudit=[auto/yes/no] Add Linux audit support [default=auto]],, + with_libaudit=auto) + +# libaudit detection +if test x$with_libaudit = xno ; then + have_libaudit=no; +else + # See if we have audit daemon library + AC_CHECK_LIB(audit, audit_log_user_message, + have_libaudit=yes, have_libaudit=no) +fi + +AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes) + +if test x$have_libaudit = xyes ; then + PAM_LIBS="$PAM_LIBS -laudit" + AC_DEFINE(HAVE_LIBAUDIT,1,[linux audit support]) +fi # Check for Solaris logindevperm support # diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 05810f61..93b18cf2 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -244,10 +244,22 @@ gdm_xdmcp_chooser_slave_LDADD = \ gdm_session_worker_SOURCES = \ session-worker-main.c \ + gdm-session-auditor.h \ + gdm-session-auditor.c \ gdm-session-worker.h \ gdm-session-worker.c \ $(NULL) +if HAVE_LIBAUDIT +gdm_session_worker_SOURCES += gdm-session-linux-auditor.h \ + gdm-session-linux-auditor.c +endif + +if HAVE_ADT +gdm_session_worker_SOURCES += gdm-session-solaris-auditor.h \ + gdm-session-solaris-auditor.c +endif + gdm_session_worker_LDFLAGS = \ $(PAM_LIBS) \ $(NULL) diff --git a/daemon/gdm-session-auditor.c b/daemon/gdm-session-auditor.c new file mode 100644 index 00000000..f656511e --- /dev/null +++ b/daemon/gdm-session-auditor.c @@ -0,0 +1,305 @@ +/* gdm-session-auditor.c - Object for auditing session login/logout + * + * Copyright (C) 2004, 2008 Sun Microsystems + * Copyright (C) 2005, 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Brian A. Cameron <Brian.Cameron@sun.com> + * Gary Winiger <Gary.Winiger@sun.com> + * Ray Strode <rstrode@redhat.com> + * Steve Grubb <sgrubb@redhat.com> + */ +#include "config.h" +#include "gdm-session-auditor.h" + +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include <glib.h> +#include <glib-object.h> +#include <glib/gi18n.h> + +struct _GdmSessionAuditorPrivate +{ + char *username; + char *hostname; + char *display_device; +}; + +static void gdm_session_auditor_finalize (GObject *object); +static void gdm_session_auditor_class_install_properties (GdmSessionAuditorClass * + auditor_class); + +static void gdm_session_auditor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gdm_session_auditor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +enum { + PROP_0 = 0, + PROP_USERNAME, + PROP_HOSTNAME, + PROP_DISPLAY_DEVICE +}; + +G_DEFINE_TYPE (GdmSessionAuditor, gdm_session_auditor, G_TYPE_OBJECT); + +static void +gdm_session_auditor_class_init (GdmSessionAuditorClass *auditor_class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (auditor_class); + + object_class->finalize = gdm_session_auditor_finalize; + + gdm_session_auditor_class_install_properties (auditor_class); + + g_type_class_add_private (auditor_class, sizeof (GdmSessionAuditorPrivate)); +} + +static void +gdm_session_auditor_class_install_properties (GdmSessionAuditorClass *auditor_class) +{ + GObjectClass *object_class; + GParamSpec *param_spec; + + object_class = G_OBJECT_CLASS (auditor_class); + object_class->set_property = gdm_session_auditor_set_property; + object_class->get_property = gdm_session_auditor_get_property; + + param_spec = g_param_spec_string ("username", _("Username"), + _("The username"), + NULL, G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_USERNAME, param_spec); + + param_spec = g_param_spec_string ("hostname", _("Hostname"), + _("The hostname"), + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_HOSTNAME, param_spec); + + param_spec = g_param_spec_string ("display-device", _("Display Device"), + _("The display device"), + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_DISPLAY_DEVICE, param_spec); +} + +static void +gdm_session_auditor_init (GdmSessionAuditor *auditor) +{ + auditor->priv = G_TYPE_INSTANCE_GET_PRIVATE (auditor, + GDM_TYPE_SESSION_AUDITOR, + GdmSessionAuditorPrivate); + +} + +static void +gdm_session_auditor_finalize (GObject *object) +{ + GdmSessionAuditor *auditor; + GObjectClass *parent_class; + + auditor = GDM_SESSION_AUDITOR (object); + + g_free (auditor->priv->username); + g_free (auditor->priv->hostname); + g_free (auditor->priv->display_device); + + parent_class = G_OBJECT_CLASS (gdm_session_auditor_parent_class); + + if (parent_class->finalize != NULL) { + parent_class->finalize (object); + } +} + +void +gdm_session_auditor_set_username (GdmSessionAuditor *auditor, + const char *username) +{ + g_return_if_fail (GDM_IS_SESSION_AUDITOR (auditor)); + + if (username == auditor->priv->username) { + return; + } + + if ((username == NULL || auditor->priv->username == NULL) || + strcmp (username, auditor->priv->username) != 0) { + auditor->priv->username = g_strdup (username); + g_object_notify (G_OBJECT (auditor), "username"); + } +} + +static void +gdm_session_auditor_set_hostname (GdmSessionAuditor *auditor, + const char *hostname) +{ + g_return_if_fail (GDM_IS_SESSION_AUDITOR (auditor)); + auditor->priv->hostname = g_strdup (hostname); +} + +static void +gdm_session_auditor_set_display_device (GdmSessionAuditor *auditor, + const char *display_device) +{ + g_return_if_fail (GDM_IS_SESSION_AUDITOR (auditor)); + auditor->priv->display_device = g_strdup (display_device); +} + +static char * +gdm_session_auditor_get_username (GdmSessionAuditor *auditor) +{ + return g_strdup (auditor->priv->username); +} + +static char * +gdm_session_auditor_get_hostname (GdmSessionAuditor *auditor) +{ + return g_strdup (auditor->priv->hostname); +} + +static char * +gdm_session_auditor_get_display_device (GdmSessionAuditor *auditor) +{ + return g_strdup (auditor->priv->display_device); +} + +static void +gdm_session_auditor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdmSessionAuditor *auditor; + + auditor = GDM_SESSION_AUDITOR (object); + + switch (prop_id) { + case PROP_USERNAME: + gdm_session_auditor_set_username (auditor, g_value_get_string (value)); + break; + + case PROP_HOSTNAME: + gdm_session_auditor_set_hostname (auditor, g_value_get_string (value)); + break; + + case PROP_DISPLAY_DEVICE: + gdm_session_auditor_set_display_device (auditor, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gdm_session_auditor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdmSessionAuditor *auditor; + + auditor = GDM_SESSION_AUDITOR (object); + + switch (prop_id) { + case PROP_USERNAME: + g_value_set_string (value, gdm_session_auditor_get_username (auditor)); + break; + + case PROP_HOSTNAME: + g_value_set_string (value, gdm_session_auditor_get_hostname (auditor)); + break; + + case PROP_DISPLAY_DEVICE: + g_value_set_string (value, gdm_session_auditor_get_display_device (auditor)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +GdmSessionAuditor * +gdm_session_auditor_new (const char *hostname, + const char *display_device) +{ + GdmSessionAuditor *auditor; + + auditor = g_object_new (GDM_TYPE_SESSION_AUDITOR, + "hostname", hostname, + "display-device", display_device, + NULL); + + return auditor; +} + +void +gdm_session_auditor_report_password_changed (GdmSessionAuditor *auditor) +{ + if (GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_password_changed != NULL) { + GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_password_changed (auditor); + } +} + +void +gdm_session_auditor_report_password_change_failure (GdmSessionAuditor *auditor) +{ + if (GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_password_change_failure != NULL) { + GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_password_change_failure (auditor); + } +} + +void +gdm_session_auditor_report_user_accredited (GdmSessionAuditor *auditor) +{ + if (GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_user_accredited != NULL) { + GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_user_accredited (auditor); + } +} + +void +gdm_session_auditor_report_login (GdmSessionAuditor *auditor) +{ + if (GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_login != NULL) { + GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_login (auditor); + } +} + +void +gdm_session_auditor_report_login_failure (GdmSessionAuditor *auditor, + int error_code, + const char *error_message) +{ + if (GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_login_failure != NULL) { + GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_login_failure (auditor, error_code, error_message); + } +} + +void +gdm_session_auditor_report_logout (GdmSessionAuditor *auditor) +{ + if (GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_logout != NULL) { + GDM_SESSION_AUDITOR_GET_CLASS (auditor)->report_logout (auditor); + } +} diff --git a/daemon/gdm-session-auditor.h b/daemon/gdm-session-auditor.h new file mode 100644 index 00000000..76480925 --- /dev/null +++ b/daemon/gdm-session-auditor.h @@ -0,0 +1,81 @@ +/* gdm-session-auditor.h - Object for auditing session login/logout + * + * Copyright (C) 2004, 2008 Sun Microsystems + * Copyright (C) 2005, 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Brian A. Cameron <Brian.Cameron@sun.com> + * Gary Winiger <Gary.Winiger@sun.com> + * Ray Strode <rstrode@redhat.com> + * Steve Grubb <sgrubb@redhat.com> + */ +#ifndef GDM_SESSION_AUDITOR_H +#define GDM_SESSION_AUDITOR_H + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS +#define GDM_TYPE_SESSION_AUDITOR (gdm_session_auditor_get_type ()) +#define GDM_SESSION_AUDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SESSION_AUDITOR, GdmSessionAuditor)) +#define GDM_SESSION_AUDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SESSION_AUDITOR, GdmSessionAuditorClass)) +#define GDM_IS_SESSION_AUDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SESSION_AUDITOR)) +#define GDM_IS_SESSION_AUDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION_AUDITOR)) +#define GDM_SESSION_AUDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION_AUDITOR, GdmSessionAuditorClass)) +#define GDM_SESSION_AUDITOR_ERROR (gdm_session_auditor_error_quark ()) +typedef struct _GdmSessionAuditor GdmSessionAuditor; +typedef struct _GdmSessionAuditorClass GdmSessionAuditorClass; +typedef struct _GdmSessionAuditorPrivate GdmSessionAuditorPrivate; + +struct _GdmSessionAuditor +{ + GObject parent; + + /*< private > */ + GdmSessionAuditorPrivate *priv; +}; + +struct _GdmSessionAuditorClass +{ + GObjectClass parent_class; + + void (* report_password_changed) (GdmSessionAuditor *auditor); + void (* report_password_change_failure) (GdmSessionAuditor *auditor); + void (* report_user_accredited) (GdmSessionAuditor *auditor); + void (* report_login) (GdmSessionAuditor *auditor); + void (* report_login_failure) (GdmSessionAuditor *auditor, + int error_code, + const char *error_message); + void (* report_logout) (GdmSessionAuditor *auditor); +}; + +GType gdm_session_auditor_get_type (void); +GdmSessionAuditor *gdm_session_auditor_new (const char *hostname, + const char *display_device); +void gdm_session_auditor_set_username (GdmSessionAuditor *auditor, + const char *username); +void gdm_session_auditor_report_password_changed (GdmSessionAuditor *auditor); +void gdm_session_auditor_report_password_change_failure (GdmSessionAuditor *auditor); +void gdm_session_auditor_report_user_accredited (GdmSessionAuditor *auditor); +void gdm_session_auditor_report_login (GdmSessionAuditor *auditor); +void gdm_session_auditor_report_login_failure (GdmSessionAuditor *auditor, + int error_code, + const char *error_message); +void gdm_session_auditor_report_logout (GdmSessionAuditor *auditor); + +G_END_DECLS +#endif /* GDM_SESSION_AUDITOR_H */ diff --git a/daemon/gdm-session-linux-auditor.c b/daemon/gdm-session-linux-auditor.c new file mode 100644 index 00000000..7702a45a --- /dev/null +++ b/daemon/gdm-session-linux-auditor.c @@ -0,0 +1,162 @@ +/* gdm-session-linux-auditor.c - Object for Linux auditing of session login/logout + * + * Copyright (C) 2004, 2008 Sun Microsystems + * Copyright (C) 2005, 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Brian A. Cameron <Brian.Cameron@sun.com> + * Gary Winiger <Gary.Winiger@sun.com> + * Ray Strode <rstrode@redhat.com> + * Steve Grubb <sgrubb@redhat.com> + */ +#include "config.h" +#include "gdm-session-linux-auditor.h" + +#include <fcntl.h> +#include <pwd.h> +#include <syslog.h> +#include <unistd.h> + +#include <libaudit.h> + +#include <glib.h> + +struct _GdmSessionLinuxAuditorPrivate +{ + int audit_fd; +}; + +static void gdm_session_linux_auditor_finalize (GObject *object); + +G_DEFINE_TYPE (GdmSessionLinuxAuditor, gdm_session_linux_auditor, GDM_TYPE_SESSION_AUDITOR); + +static void +gdm_session_linux_auditor_report_login_attempt (GdmSessionAuditor *auditor, + gboolean was_successful) +{ + GdmSessionLinuxAuditor *linux_auditor; + char buf[512]; + char *username; + char *hostname; + char *display_device; + struct passwd *pw; + + linux_auditor = GDM_SESSION_LINUX_AUDITOR (auditor); + + g_object_get (G_OBJECT (auditor), "username", &username, NULL); + g_object_get (G_OBJECT (auditor), "hostname", &hostname, NULL); + g_object_get (G_OBJECT (auditor), "display-device", &display_device, NULL); + + pw = getpwnam (username); + if (username) { + pw = getpwnam (username); + } else { + username = "unknown"; + pw = NULL; + } + + if (pw) { + g_snprintf (buf, sizeof (buf), "uid=%d", pw->pw_uid); + audit_log_user_message (linux_auditor->priv->audit_fd, AUDIT_USER_LOGIN, + buf, hostname, NULL, display_device, + was_successful != FALSE); + } else { + g_snprintf (buf, sizeof (buf), "acct=%s", username); + audit_log_user_message (linux_auditor->priv->audit_fd, AUDIT_USER_LOGIN, + buf, hostname, NULL, display_device, + was_successful != FALSE); + } + + g_free (username); + g_free (hostname); + g_free (display_device); +} + +static void +gdm_session_linux_auditor_report_login (GdmSessionAuditor *auditor) +{ + gdm_session_linux_auditor_report_login_attempt (auditor, TRUE); +} + +static void +gdm_session_linux_auditor_report_login_failure (GdmSessionAuditor *auditor, + int pam_error_code, + const char *pam_error_string) +{ + + gdm_session_linux_auditor_report_login_attempt (auditor, FALSE); +} + +static void +gdm_session_linux_auditor_class_init (GdmSessionLinuxAuditorClass *klass) +{ + GObjectClass *object_class; + GdmSessionAuditorClass *auditor_class; + + object_class = G_OBJECT_CLASS (klass); + auditor_class = GDM_SESSION_AUDITOR_CLASS (klass); + + object_class->finalize = gdm_session_linux_auditor_finalize; + + auditor_class->report_login = gdm_session_linux_auditor_report_login; + auditor_class->report_login_failure = gdm_session_linux_auditor_report_login_failure; + + g_type_class_add_private (auditor_class, sizeof (GdmSessionLinuxAuditorPrivate)); +} + +static void +gdm_session_linux_auditor_init (GdmSessionLinuxAuditor *auditor) +{ + auditor->priv = G_TYPE_INSTANCE_GET_PRIVATE (auditor, + GDM_TYPE_SESSION_LINUX_AUDITOR, + GdmSessionLinuxAuditorPrivate); + + auditor->priv->audit_fd = audit_open (); +} + +static void +gdm_session_linux_auditor_finalize (GObject *object) +{ + GdmSessionLinuxAuditor *linux_auditor; + GObjectClass *parent_class; + + linux_auditor = GDM_SESSION_LINUX_AUDITOR (object); + + close (linux_auditor->priv->audit_fd); + + parent_class = G_OBJECT_CLASS (gdm_session_linux_auditor_parent_class); + if (parent_class->finalize != NULL) { + parent_class->finalize (object); + } +} + + +GdmSessionAuditor * +gdm_session_linux_auditor_new (const char *hostname, + const char *display_device) +{ + GObject *auditor; + + auditor = g_object_new (GDM_TYPE_SESSION_LINUX_AUDITOR, + "hostname", hostname, + "display-device", display_device, + NULL); + + return GDM_SESSION_AUDITOR (auditor); +} + + diff --git a/daemon/gdm-session-linux-auditor.h b/daemon/gdm-session-linux-auditor.h new file mode 100644 index 00000000..6d07af8a --- /dev/null +++ b/daemon/gdm-session-linux-auditor.h @@ -0,0 +1,63 @@ +/* gdm-linux-session-auditor.h - Object for linux auditing of session login/logout + * + * Copyright (C) 2004, 2008 Sun Microsystems + * Copyright (C) 2005, 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Brian A. Cameron <Brian.Cameron@sun.com> + * Gary Winiger <Gary.Winiger@sun.com> + * Ray Strode <rstrode@redhat.com> + * Steve Grubb <sgrubb@redhat.com> + */ +#ifndef GDM_SESSION_LINUX_AUDITOR_H +#define GDM_SESSION_LINUX_AUDITOR_H + +#include <glib.h> +#include <glib-object.h> + +#include "gdm-session-auditor.h" + +G_BEGIN_DECLS +#define GDM_TYPE_SESSION_LINUX_AUDITOR (gdm_session_linux_auditor_get_type ()) +#define GDM_SESSION_LINUX_AUDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SESSION_LINUX_AUDITOR, GdmSessionLinuxAuditor)) +#define GDM_SESSION_LINUX_AUDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SESSION_LINUX_AUDITOR, GdmSessionLinuxAuditorClass)) +#define GDM_IS_SESSION_LINUX_AUDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SESSION_LINUX_AUDITOR)) +#define GDM_IS_SESSION_LINUX_AUDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION_LINUX_AUDITOR)) +#define GDM_SESSION_LINUX_AUDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION_LINUX_AUDITOR, GdmSessionLinuxAuditorClass)) +#define GDM_SESSION_LINUX_AUDITOR_ERROR (gdm_session_linux_auditor_error_quark ()) +typedef struct _GdmSessionLinuxAuditor GdmSessionLinuxAuditor; +typedef struct _GdmSessionLinuxAuditorClass GdmSessionLinuxAuditorClass; +typedef struct _GdmSessionLinuxAuditorPrivate GdmSessionLinuxAuditorPrivate; + +struct _GdmSessionLinuxAuditor +{ + GdmSessionAuditor parent; + + /*< private > */ + GdmSessionLinuxAuditorPrivate *priv; +}; + +struct _GdmSessionLinuxAuditorClass +{ + GdmSessionAuditorClass parent_class; +}; + +GType gdm_session_linux_auditor_get_type (void); +GdmSessionAuditor *gdm_session_linux_auditor_new (const char *hostname, + const char *display_device); +G_END_DECLS +#endif /* GDM_SESSION_LINUX_AUDITOR_H */ diff --git a/daemon/gdm-session-solaris-auditor.c b/daemon/gdm-session-solaris-auditor.c new file mode 100644 index 00000000..80dbd164 --- /dev/null +++ b/daemon/gdm-session-solaris-auditor.c @@ -0,0 +1,391 @@ +/* gdm-session-solaris-auditor.c - Object for Solaris auditing of session login/logout + * + * Copyright (C) 2004, 2008 Sun Microsystems + * Copyright (C) 2005, 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Brian A. Cameron <Brian.Cameron@sun.com> + * Gary Winiger <Gary.Winiger@sun.com> + * Ray Strode <rstrode@redhat.com> + * Steve Grubb <sgrubb@redhat.com> + */ +#include "config.h" +#include "gdm-session-solaris-auditor.h" + +#include <syslog.h> +#include <security/pam_appl.h> +#include <pwd.h> + +#include <fcntl.h> +#include <bsm/adt.h> +#include <bsm/adt_event.h> + +#include <glib.h> +#include <glib-object.h> +#include <glib/gi18n.h> + +struct _GdmSessionSolarisAuditorPrivate +{ + adt_session_data_t *audit_session_handle; + + guint password_change_initiated : 1; + guint password_changed : 1; + guint user_accredited : 1; + + /* cached values to prevent repeated calls + * to getpwnam + */ + char *username; + uid_t uid; + gid_t gid; +}; + +static void gdm_session_solaris_auditor_finalize (GObject *object); + +G_DEFINE_TYPE (GdmSessionSolarisAuditor, gdm_session_solaris_auditor, GDM_TYPE_SESSION_AUDITOR) + +static void +gdm_session_solaris_auditor_report_password_changed (GdmSessionAuditor *auditor) +{ + GdmSessionSolarisAuditor *solaris_auditor; + + solaris_auditor = GDM_SESSION_SOLARIS_AUDITOR (auditor); + solaris_auditor->priv->password_change_initiated = TRUE; + solaris_auditor->priv->password_changed = TRUE; +} + +static void +gdm_session_solaris_auditor_report_password_change_failure (GdmSessionAuditor *auditor) +{ + GdmSessionSolarisAuditor *solaris_auditor; + + solaris_auditor = GDM_SESSION_SOLARIS_AUDITOR (auditor); + solaris_auditor->priv->password_change_initiated = TRUE; + solaris_auditor->priv->password_changed = FALSE; +} + +static void +gdm_session_solaris_auditor_report_user_accredited (GdmSessionAuditor *auditor) +{ + GdmSessionSolarisAuditor *solaris_auditor; + + solaris_auditor = GDM_SESSION_SOLARIS_AUDITOR (auditor); + solaris_auditor->priv->user_accredited = TRUE; +} + +static void +gdm_session_solaris_auditor_report_login (GdmSessionAuditor *auditor) +{ + GdmSessionSolarisAuditor *solaris_auditor; + adt_session_data_t *adt_ah; /* Audit session handle */ + adt_event_data_t *event; /* Event to generate */ + + solaris_auditor = GDM_SESSION_SOLARIS_AUDITOR (auditor); + + g_return_if_fail (solaris_auditor->priv->username != NULL); + + adt_ah = NULL; + if (adt_start_session (&adt_ah, NULL, ADT_USE_PROC_DATA) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_start_session (ADT_login): %m"); + goto cleanup; + } + + if (adt_set_user (adt_ah, solaris_auditor->priv->uid, + solaris_auditor->priv->gid, solaris_auditor->priv->uid, + solaris_auditor->priv->gid, NULL, ADT_USER) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_set_user (ADT_login, %s): %m", + solaris_auditor->priv->username); + } + + event = adt_alloc_event (adt_ah, ADT_login); + if (event == NULL) { + syslog (LOG_AUTH | LOG_ALERT, "adt_alloc_event (ADT_login): %m"); + } else if (adt_put_event (event, ADT_SUCCESS, ADT_SUCCESS) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_put_event (ADT_login, ADT_SUCCESS): %m"); + } + + if (solaris_auditor->priv->password_changed) { + + g_assert (solaris_auditor->priv->password_change_initiated); + + /* Also audit password change */ + adt_free_event (event); + event = adt_alloc_event (adt_ah, ADT_passwd); + if (event == NULL) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_alloc_event (ADT_passwd): %m"); + } else if (adt_put_event (event, ADT_SUCCESS, + ADT_SUCCESS) != 0) { + + syslog (LOG_AUTH | LOG_ALERT, + "adt_put_event (ADT_passwd, ADT_SUCCESS): %m"); + } + } + + adt_free_event (event); + +cleanup: + solaris_auditor->priv->audit_session_handle = adt_ah; +} + +static void +gdm_session_solaris_auditor_report_login_failure (GdmSessionAuditor *auditor, + int pam_error_code, + const char *pam_error_string) +{ + GdmSessionSolarisAuditor *solaris_auditor; + char *hostname; + char *display_device; + adt_session_data_t *ah; /* Audit session handle */ + adt_event_data_t *event; /* Event to generate */ + adt_termid_t *tid; /* Terminal ID for failures */ + + solaris_auditor = GDM_SESSION_SOLARIS_AUDITOR (auditor); + g_object_get (G_OBJECT (auditor), + "hostname", &hostname, + "display-device", &display_device, NULL); + + if (solaris_auditor->priv->user_accredited) { + if (adt_start_session (&ah, NULL, ADT_USE_PROC_DATA) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_start_session (ADT_login, ADT_FAILURE): %m"); + goto cleanup; + } + } else { + if (adt_start_session (&ah, NULL, 0) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_start_session (ADT_login, ADT_FAILURE): %m"); + goto cleanup; + } + + /* If display is on console or VT */ + if (hostname != NULL && hostname[0] != '\0') { + /* login from the local host */ + if (adt_load_ttyname (display_device, &tid) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_loadhostname (localhost): %m"); + } + } else { + /* Login from a remote host */ + if (adt_load_hostname (hostname, &tid) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_loadhostname (%s): %m", hostname); + } + } + + if (adt_set_user (ah, + solaris_auditor->priv->username != NULL ? solaris_auditor->priv->uid : ADT_NO_ATTRIB, + solaris_auditor->priv->username != NULL ? solaris_auditor->priv->gid : ADT_NO_ATTRIB, + solaris_auditor->priv->username != NULL ? solaris_auditor->priv->uid : ADT_NO_ATTRIB, + solaris_auditor->priv->username != NULL ? solaris_auditor->priv->gid : ADT_NO_ATTRIB, + tid, ADT_NEW) != 0) { + + syslog (LOG_AUTH | LOG_ALERT, + "adt_set_user (%s): %m", + solaris_auditor->priv->username != NULL ? solaris_auditor->priv->username : "ADT_NO_ATTRIB"); + } + } + + event = adt_alloc_event (ah, ADT_login); + + if (event == NULL) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_alloc_event (ADT_login, ADT_FAILURE): %m"); + goto done; + } else if (adt_put_event (event, ADT_FAILURE, + ADT_FAIL_PAM + pam_error_code) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_put_event (ADT_login (ADT_FAIL, %s): %m", + pam_error_string); + } + + if (solaris_auditor->priv->password_change_initiated) { + /* Also audit password change */ + adt_free_event (event); + + event = adt_alloc_event (ah, ADT_passwd); + if (event == NULL) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_alloc_event (ADT_passwd): %m"); + goto done; + } + + if (solaris_auditor->priv->password_changed) { + if (adt_put_event (event, ADT_SUCCESS, + ADT_SUCCESS) != 0) { + + syslog (LOG_AUTH | LOG_ALERT, + "adt_put_event (ADT_passwd, ADT_SUCCESS): " + "%m"); + } + } else { + if (adt_put_event (event, ADT_FAILURE, + ADT_FAIL_PAM + pam_error_code) != 0) { + + syslog (LOG_AUTH | LOG_ALERT, + "adt_put_event (ADT_passwd, ADT_FAILURE): " + "%m"); + } + } + } + adt_free_event (event); + +done: + /* Reset process audit state. this process is being reused.*/ + if ((adt_set_user (ah, ADT_NO_AUDIT, ADT_NO_AUDIT, ADT_NO_AUDIT, + ADT_NO_AUDIT, NULL, ADT_NEW) != 0) || + (adt_set_proc (ah) != 0)) { + + syslog (LOG_AUTH | LOG_ALERT, + "adt_put_event (ADT_login (ADT_FAILURE reset, %m)"); + } + (void) adt_end_session (ah); + +cleanup: + g_free (hostname); + g_free (display_device); +} + +static void +gdm_session_solaris_auditor_report_logout (GdmSessionAuditor *auditor) +{ + GdmSessionSolarisAuditor *solaris_auditor; + adt_session_data_t *adt_ah; /* Audit session handle */ + adt_event_data_t *event; /* Event to generate */ + + solaris_auditor = GDM_SESSION_SOLARIS_AUDITOR (auditor); + + adt_ah = solaris_auditor->priv->audit_session_handle; + + event = adt_alloc_event (adt_ah, ADT_logout); + if (event == NULL) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_alloc_event (ADT_logout): %m"); + } else if (adt_put_event (event, ADT_SUCCESS, ADT_SUCCESS) != 0) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_put_event (ADT_logout, ADT_SUCCESS): %m"); + } + + adt_free_event (event); + + /* Reset process audit state. this process is being reused. */ + if ((adt_set_user (adt_ah, ADT_NO_AUDIT, ADT_NO_AUDIT, ADT_NO_AUDIT, + ADT_NO_AUDIT, NULL, ADT_NEW) != 0) || + (adt_set_proc (adt_ah) != 0)) { + syslog (LOG_AUTH | LOG_ALERT, + "adt_set_proc (ADT_logout reset): %m"); + } + + (void) adt_end_session (adt_ah); + solaris_auditor->priv->audit_session_handle = NULL; +} + +static void +gdm_session_solaris_auditor_class_init (GdmSessionSolarisAuditorClass *klass) +{ + GObjectClass *object_class; + GdmSessionAuditorClass *auditor_class; + + object_class = G_OBJECT_CLASS (klass); + auditor_class = GDM_SESSION_AUDITOR_CLASS (klass); + + object_class->finalize = gdm_session_solaris_auditor_finalize; + + auditor_class->report_password_changed = gdm_session_solaris_auditor_report_password_changed; + auditor_class->report_password_change_failure = gdm_session_solaris_auditor_report_password_change_failure; + auditor_class->report_user_accredited = gdm_session_solaris_auditor_report_user_accredited; + auditor_class->report_login = gdm_session_solaris_auditor_report_login; + auditor_class->report_login_failure = gdm_session_solaris_auditor_report_login_failure; + auditor_class->report_logout = gdm_session_solaris_auditor_report_logout; + + g_type_class_add_private (auditor_class, sizeof (GdmSessionSolarisAuditorPrivate)); +} + +static void +on_username_set (GdmSessionSolarisAuditor *auditor) +{ + char *username; + struct passwd *passwd_entry; + + g_object_get (G_OBJECT (auditor), "username", &username, NULL); + + passwd_entry = getpwnam (username); + + if (passwd_entry != NULL) { + auditor->priv->uid = passwd_entry->pw_uid; + auditor->priv->gid = passwd_entry->pw_gid; + auditor->priv->username = g_strdup (passwd_entry->pw_name); + } else { + g_free (auditor->priv->username); + auditor->priv->username = NULL; + auditor->priv->uid = (uid_t) -1; + auditor->priv->gid = (gid_t) -1; + } + + g_free (username); +} + +static void +gdm_session_solaris_auditor_init (GdmSessionSolarisAuditor *auditor) +{ + auditor->priv = G_TYPE_INSTANCE_GET_PRIVATE (auditor, + GDM_TYPE_SESSION_SOLARIS_AUDITOR, + GdmSessionSolarisAuditorPrivate); + + g_signal_connect (G_OBJECT (auditor), "notify::username", + G_CALLBACK (on_username_set), NULL); + + auditor->priv->uid = (uid_t) -1; + auditor->priv->gid = (gid_t) -1; +} + +static void +gdm_session_solaris_auditor_finalize (GObject *object) +{ + GdmSessionSolarisAuditor *solaris_auditor; + GObjectClass *parent_class; + + solaris_auditor = GDM_SESSION_SOLARIS_AUDITOR (object); + + g_free (solaris_auditor->priv->username); + solaris_auditor->priv->username = NULL; + + parent_class = G_OBJECT_CLASS (gdm_session_solaris_auditor_parent_class); + + if (parent_class->finalize != NULL) { + parent_class->finalize (object); + } +} + +GdmSessionAuditor * +gdm_session_solaris_auditor_new (const char *hostname, + const char *display_device) +{ + GObject *auditor; + + auditor = g_object_new (GDM_TYPE_SESSION_SOLARIS_AUDITOR, + "hostname", hostname, + "display-device", display_device, + NULL); + + return GDM_SESSION_AUDITOR (auditor); +} + + diff --git a/daemon/gdm-session-solaris-auditor.h b/daemon/gdm-session-solaris-auditor.h new file mode 100644 index 00000000..1826b3cf --- /dev/null +++ b/daemon/gdm-session-solaris-auditor.h @@ -0,0 +1,63 @@ +/* gdm-solaris-session-auditor.h - Object for solaris auditing of session login/logout + * + * Copyright (C) 2004, 2008 Sun Microsystems + * Copyright (C) 2005, 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Brian A. Cameron <Brian.Cameron@sun.com> + * Gary Winiger <Gary.Winiger@sun.com> + * Ray Strode <rstrode@redhat.com> + * Steve Grubb <sgrubb@redhat.com> + */ +#ifndef GDM_SESSION_SOLARIS_AUDITOR_H +#define GDM_SESSION_SOLARIS_AUDITOR_H + +#include <glib.h> +#include <glib-object.h> + +#include "gdm-session-auditor.h" + +G_BEGIN_DECLS +#define GDM_TYPE_SESSION_SOLARIS_AUDITOR (gdm_session_solaris_auditor_get_type ()) +#define GDM_SESSION_SOLARIS_AUDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SESSION_SOLARIS_AUDITOR, GdmSessionSolarisAuditor)) +#define GDM_SESSION_SOLARIS_AUDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SESSION_SOLARIS_AUDITOR, GdmSessionSolarisAuditorClass)) +#define GDM_IS_SESSION_SOLARIS_AUDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SESSION_SOLARIS_AUDITOR)) +#define GDM_IS_SESSION_SOLARIS_AUDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION_SOLARIS_AUDITOR)) +#define GDM_SESSION_SOLARIS_AUDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION_SOLARIS_AUDITOR, GdmSessionSolarisAuditorClass)) +#define GDM_SESSION_SOLARIS_AUDITOR_ERROR (gdm_session_solaris_auditor_error_quark ()) +typedef struct _GdmSessionSolarisAuditor GdmSessionSolarisAuditor; +typedef struct _GdmSessionSolarisAuditorClass GdmSessionSolarisAuditorClass; +typedef struct _GdmSessionSolarisAuditorPrivate GdmSessionSolarisAuditorPrivate; + +struct _GdmSessionSolarisAuditor +{ + GdmSessionAuditor parent; + + /*< private > */ + GdmSessionSolarisAuditorPrivate *priv; +}; + +struct _GdmSessionSolarisAuditorClass +{ + GdmSessionAuditorClass parent_class; +}; + +GType gdm_session_solaris_auditor_get_type (void); +GdmSessionAuditor *gdm_session_solaris_auditor_new (const char *hostname, + const char *display_device); +G_END_DECLS +#endif /* GDM_SESSION_SOLARIS_AUDITOR_H */ diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index 0558ca7e..2a317c56 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -46,6 +46,14 @@ #include "gdm-session-worker.h" #include "gdm-marshal.h" +#if defined (HAVE_ADT) +#include "gdm-session-solaris-auditor.h" +#elif defined (HAVE_LIBAUDIT) +#include "gdm-session-linux-auditor.h" +#else +#include "gdm-session-auditor.h" +#endif + #define GDM_SESSION_WORKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerPrivate)) #define GDM_SESSION_DBUS_PATH "/org/gnome/DisplayManager/Session" @@ -110,6 +118,8 @@ struct GdmSessionWorkerPrivate char *server_address; DBusConnection *connection; + + GdmSessionAuditor *auditor; }; enum { @@ -496,6 +506,8 @@ gdm_session_worker_update_username (GdmSessionWorker *worker) worker->priv->username = username; username = NULL; + gdm_session_auditor_set_username (worker->priv->auditor, worker->priv->username); + send_dbus_string_method (worker->priv->connection, "UsernameChanged", worker->priv->username); @@ -773,6 +785,32 @@ gdm_session_worker_pam_new_messages_handler (int number_o } static void +gdm_session_worker_start_auditor (GdmSessionWorker *worker) +{ + +/* FIXME: it may make sense at some point to keep a list of + * auditors, instead of assuming they are mutually exclusive + */ +#if defined (HAVE_ADT) + worker->priv->auditor = gdm_session_solaris_auditor_new (worker->priv->hostname, + worker->priv->display_device); +#elif defined (HAVE_LIBAUDIT) + worker->priv->auditor = gdm_session_linux_auditor_new (worker->priv->hostname, + worker->priv->display_device); +#else + worker->priv->auditor = gdm_session_auditor_new (worker->priv->hostname, + worker->priv->display_device); +#endif +} + +static void +gdm_session_worker_stop_auditor (GdmSessionWorker *worker) +{ + g_object_unref (worker->priv->auditor); + worker->priv->auditor = NULL; +} + +static void gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, int status) { @@ -787,11 +825,18 @@ gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) { pam_close_session (worker->priv->pam_handle, 0); + gdm_session_auditor_report_logout (worker->priv->auditor); + } else { + gdm_session_auditor_report_login_failure (worker->priv->auditor, + status, + pam_strerror (worker->priv->pam_handle, status)); } pam_end (worker->priv->pam_handle, status); worker->priv->pam_handle = NULL; + gdm_session_worker_stop_auditor (worker); + g_debug ("GdmSessionWorker: state NONE"); worker->priv->state = GDM_SESSION_WORKER_STATE_NONE; } @@ -802,8 +847,9 @@ _get_tty_for_pam (const char *x11_display_name, { #ifdef __sun return g_strdup (display_device); -#endif +#else return g_strdup (x11_display_name); +#endif } static gboolean @@ -827,6 +873,7 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, pam_conversation.conv = (GdmSessionWorkerPamNewMessagesFunc) gdm_session_worker_pam_new_messages_handler; pam_conversation.appdata_ptr = worker; + gdm_session_worker_start_auditor (worker); error_code = pam_start (service, username, &pam_conversation, @@ -966,9 +1013,16 @@ gdm_session_worker_authorize_user (GdmSessionWorker *worker, /* it's possible that the user needs to change their password or pin code */ - if (error_code == PAM_NEW_AUTHTOK_REQD) + if (error_code == PAM_NEW_AUTHTOK_REQD) { error_code = pam_chauthtok (worker->priv->pam_handle, PAM_CHANGE_EXPIRED_AUTHTOK); + if (error_code != PAM_SUCCESS) { + gdm_session_auditor_report_password_change_failure (worker->priv->auditor); + } else { + gdm_session_auditor_report_password_changed (worker->priv->auditor); + } + } + if (error_code != PAM_SUCCESS) { g_debug ("GdmSessionWorker: user is not authorized to log in: %s", pam_strerror (worker->priv->pam_handle, error_code)); @@ -1144,6 +1198,8 @@ gdm_session_worker_accredit_user (GdmSessionWorker *worker, goto out; } + gdm_session_auditor_report_user_accredited (worker->priv->auditor); + g_debug ("GdmSessionWorker: state ACCREDITED"); worker->priv->state = GDM_SESSION_WORKER_STATE_ACCREDITED; @@ -1445,6 +1501,8 @@ gdm_session_worker_open_user_session (GdmSessionWorker *worker, return FALSE; } + gdm_session_auditor_report_login (worker->priv->auditor); + return TRUE; } |