[gdm-list] Audit code for GDM




Jon/Ray:

Attached please find code that should implement audit for
GDM 2.21.  I have made the code so it should work with both
Solaris and Linux libaudit auditing.

Ray, could you test this out on Linux?  I think it should work,
but I haven't tested it.

I suspect that you might want to clean this code up a bit.  It
might be nicer if it were making use of GObjects and subclassing
rather than #ifdef's.  Not sure...

However, I think I have abstracted things out so both Solaris
and libaudit interfaces are hidden behind a more general interface
that seems reasonable enough to me.

If you would like me to further improve the patch, or make changes,
then just let me know.

I'm cc:ing Gary Winiger from Sun since he wrote the original
Solaris audit code for GDM.  This code is basically a copy with
some minor changes.  Now passing values in/out of functions
rather than using global variables for example.

I remember Steve Grubb wrote the original GDM libaudit code (refer
to bug #349835).  I'm also cc:ing him.

Now I'll be busy trying to get ConsoleKit and GDM 2.21 working
with RBAC for shutdown/suspend instead of PolicyKit.  That should
keep me busy a day or two.

Thanks,

Brian
Index: configure.ac
===================================================================
--- configure.ac	(revision 5632)
+++ configure.ac	(working copy)
@@ -964,12 +964,34 @@
 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
 
+# 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
 #
 AC_MSG_CHECKING(for Solaris di_devperm_login)
Index: daemon/gdm-session-worker.c
===================================================================
--- daemon/gdm-session-worker.c	(revision 5632)
+++ daemon/gdm-session-worker.c	(working copy)
@@ -45,6 +45,7 @@
 
 #include "gdm-session-worker.h"
 #include "gdm-marshal.h"
+#include "gdm-audit.h"
 
 #define GDM_SESSION_WORKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerPrivate))
 
@@ -98,6 +99,8 @@
         char             *hostname;
         char             *username;
         gboolean          password_is_required;
+        gpointer         *audit_data;
+        GdmPasswdChange   pw_change;
 
         int               cred_flags;
 
@@ -775,17 +778,29 @@
 gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
                                      int               status)
 {
+        gboolean did_setcred = FALSE;
+
         g_debug ("GdmSessionWorker: uninitializing PAM");
 
         if (worker->priv->pam_handle == NULL)
                 return;
 
         if (worker->priv->state >= GDM_SESSION_WORKER_STATE_ACCREDITED) {
+                did_setcred = TRUE;
                 pam_setcred (worker->priv->pam_handle, PAM_DELETE_CRED);
         }
 
         if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) {
                 pam_close_session (worker->priv->pam_handle, 0);
+                gdm_audit_logout (worker->priv->audit_data);
+        } else {
+                gdm_audit_login_failure (worker->priv->username,
+                                         worker->priv->hostname,
+                                         worker->priv->display_device,
+                                         worker->priv->pw_change,
+                                         did_setcred,
+                                         status,
+                                         pam_strerror (worker->priv->pam_handle, status));
         }
 
         pam_end (worker->priv->pam_handle, status);
@@ -801,8 +816,9 @@
 {
 #ifdef __sun
         return g_strdup (display_device);
+#else
+        return g_strdup (x11_display_name);
 #endif
-        return g_strdup (x11_display_name);
 }
 
 static gboolean
@@ -964,9 +980,16 @@
 
         /* 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) {
+                        worker->priv->pw_change = GDM_PW_FAILED;
+                } else {
+                        worker->priv->pw_change = GDM_PW_TRUE;
+                }
+        }
+
         if (error_code != PAM_SUCCESS) {
                 g_debug ("GdmSessionWorker: user is not authorized to log in: %s",
                          pam_strerror (worker->priv->pam_handle, error_code));
@@ -1444,6 +1467,12 @@
                 return FALSE;
         }
 
+        worker->priv->audit_data = 
+                gdm_audit_login_success (worker->priv->username,
+                                         worker->priv->hostname,
+                                         worker->priv->display_device,
+                                         worker->priv->pw_change);
+
         return TRUE;
 }
 
@@ -1808,6 +1837,8 @@
                 worker->priv->display_device = g_strdup (console);
                 worker->priv->hostname = g_strdup (hostname);
                 worker->priv->username = NULL;
+                worker->priv->audit_data = NULL;
+                worker->priv->pw_change = GDM_PW_FALSE;
 
                 g_debug ("GdmSessionWorker: queing setup: %s %s", service, console);
                 queue_state_change (worker);
@@ -1846,6 +1877,8 @@
                 worker->priv->display_device = g_strdup (console);
                 worker->priv->hostname = g_strdup (hostname);
                 worker->priv->username = g_strdup (username);
+                worker->priv->audit_data = NULL;
+                worker->priv->pw_change = GDM_PW_FALSE;
 
                 g_debug ("GdmSessionWorker: queuing setup for user %s %s", service, console);
                 queue_state_change (worker);
Index: daemon/Makefile.am
===================================================================
--- daemon/Makefile.am	(revision 5632)
+++ daemon/Makefile.am	(working copy)
@@ -210,6 +210,12 @@
 
 gdm_session_worker_SOURCES = 			\
 	session-worker-main.c 			\
+	gdm-audit.h				\
+	gdm-audit.c				\
+	gdm-audit-solaris.h			\
+	gdm-audit-solaris.c			\
+	gdm-audit-libaudit.h			\
+	gdm-audit-libaudit.c			\
 	gdm-session-worker.h			\
 	gdm-session-worker.c			\
 	$(NULL)
--- /dev/null	2008-01-24 19:59:34.000000000 -0600
+++ daemon/gdm-audit.h	2008-01-24 18:59:10.096253000 -0600
@@ -0,0 +1,49 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Brian A. Cameron <Brian Cameron sun com>
+ *
+ * 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 of the License, 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.
+ *
+ */
+
+
+#ifndef __GDM_AUDIT_H
+#define __GDM_AUDIT_H
+
+G_BEGIN_DECLS
+
+typedef enum {
+        GDM_PW_FALSE  = 1,   /* no password change */
+        GDM_PW_TRUE   = 2,   /* successful password change */
+        GDM_PW_FAILED = 3    /* failed password change */
+} GdmPasswdChange;
+
+gpointer   gdm_audit_login_success               (char *username,
+                                                  char *hostname,
+                                                  char *display_device,
+                                                  GdmPasswdChange pw_change);
+void       gdm_audit_login_failure               (char *username,
+                                                  char *hostname,
+                                                  char *display_device,
+                                                  GdmPasswdChange pw_change,
+                                                  gboolean did_setcred,
+                                                  int pam_error_code,
+                                                  char *pam_error_string);
+
+void       gdm_audit_logout                      (gpointer data);
+
+G_END_DECLS
+
+#endif /* __GDM_AUDIT_H */
--- /dev/null	2008-01-24 19:59:45.000000000 -0600
+++ daemon/gdm-audit-solaris.h	2008-01-24 19:10:43.362844000 -0600
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004 Gary Winiger <Gary Winiger sun com>
+ *
+ * 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 of the License, 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.
+ *
+ */
+
+
+#ifndef __GDM_AUDIT_SOLARIS_H
+#define __GDM_AUDIT_SOLARIS_H
+
+G_BEGIN_DECLS
+
+gpointer   gdm_solaris_audit_success_login       (char *username, 
+                                                  GdmPasswdChange pw_change);
+
+void       gdm_solaris_audit_fail_login          (char *username,
+                                                  char *hostname,
+                                                  char *device_name,
+                                                  GdmPasswdChange pw_change,
+                                                  gboolean did_setcred,
+                                                  int pam_error_code,
+                                                  char *pam_error_string);
+
+void       gdm_solaris_audit_logout              (gpointer data);
+
+G_END_DECLS
+
+#endif /* __GDM_AUDIT_SOLARIS_H */
--- /dev/null	2008-01-24 19:59:51.000000000 -0600
+++ daemon/gdm-audit-libaudit.h	2008-01-24 19:11:05.087705000 -0600
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Steve Grubb <sgrubb redhat com>
+ *
+ * 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 of the License, 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.
+ *
+ */
+
+
+#ifndef __GDM_AUDIT_LIBAUDIT
+#define __GDM_AUDIT_LIBAUDIT_H
+
+G_BEGIN_DECLS
+
+gpointer   gdm_libaudit_audit_success_login      (char *username, 
+                                                  GdmPasswdChange pw_change);
+
+void       gdm_libaudit_audit_fail_login         (char *username,
+                                                  char *hostname,
+                                                  char *device_name,
+                                                  GdmPasswdChange pw_change,
+                                                  gboolean did_setcred,
+                                                  int pam_error_code,
+                                                  char *pam_error_string);
+
+G_END_DECLS
+
+#endif /* __GDM_AUDIT_LIBAUDIT_H */
--- /dev/null	2008-01-24 19:59:58.000000000 -0600
+++ daemon/gdm-audit.c	2008-01-24 19:15:57.759725000 -0600
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * GDM - The GNOME Display Manager
+ * Copyright (C) 2008 Brian A. Cameron <Brian Cameron sun com>
+ *
+ * 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 of the License, 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
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "gdm-audit.h"
+
+#ifdef HAVE_ADT
+#include "gdm-audit-solaris.h"
+#endif
+
+#ifdef HAVE_LIBAUDIT
+#include "gdm-audit-libaudit.h"
+#endif
+
+gpointer
+gdm_audit_login_success (char *username,
+                         char *hostname,
+                         char *display_device,
+                         GdmPasswdChange pw_change)
+{
+#ifdef HAVE_ADT
+        return gdm_solaris_audit_success_login (username,
+                                                pw_change);
+#endif
+
+#ifdef HAVE_LIBAUDIT
+        return gdm_libaudit_log_to_audit_system (username,
+                                                 hostname,
+                                                 display_device,
+                                                 TRUE);
+#endif
+}
+
+void
+gdm_audit_login_failure (char *username,
+                         char *hostname,
+                         char *display_device,
+                         GdmPasswdChange pw_change,
+                         gboolean did_setcred,
+                         int pam_error_code,
+                         char *pam_error_string)
+{
+#ifdef HAVE_ADT
+        gdm_solaris_audit_fail_login (username,
+                                      hostname,
+                                      display_device,
+                                      pw_change,
+                                      did_setcred,
+                                      pam_error_code,
+                                      pam_error_string);
+#endif
+
+#ifdef HAVE_LIBAUDIT
+        return gdm_libaudit_log_to_audit_system (username,
+                                                 hostname,
+                                                 display_device,
+                                                 FALSE);
+#endif
+}
+
+void
+gdm_audit_logout (void *data)
+{
+#ifdef HAVE_ADT
+        gdm_solaris_audit_logout (data);
+#endif
+
+/* No-op for libaudit */
+}
+
--- /dev/null	2008-01-24 20:00:03.000000000 -0600
+++ daemon/gdm-audit-solaris.c	2008-01-24 19:59:08.191844000 -0600
@@ -0,0 +1,269 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * GDM - The GNOME Display Manager
+ * Copyright (C) 2004 Gary Winiger <Gary Winiger sun com>
+ *
+ * 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 of the License, 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
+ */
+
+#include "config.h"
+
+#ifdef HAVE_ADT
+
+#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 "gdm-audit.h"
+#include "gdm-audit-solaris.h"
+
+/*
+ * gdm_solaris_audit_success_login - Audit successful login
+ *
+ *      Entry   process audit context established -- i.e., pam_setcred ()
+ *                      called.
+ *              username = authenticated username.
+ *              pw_change == GDM_PW_TRUE, if successful password change
+ *                           audit required.
+ *
+ *      Exit    ADT_login (ADT_SUCCESS) audit record written
+ *              pw_change == GDM_PW_TRUE, ADT_passwd (ADT_SUCCESS) audit
+ *                           record written.
+ *              adt_ah = audit session established for audit_logout ();
+ */
+gpointer
+gdm_solaris_audit_success_login (char *username,
+                                 GdmPasswdChange pw_change)
+{
+        adt_session_data_t *adt_ah;  /* Audit session handle */
+        adt_event_data_t   *event;   /* Event to generate */
+        struct passwd      *pwent;
+       
+        adt_ah = NULL;
+        pwent  = getpwnam (username);
+
+        if (adt_start_session (&adt_ah, NULL, ADT_USE_PROC_DATA) != 0) {
+                syslog (LOG_AUTH | LOG_ALERT,
+                        "adt_start_session (ADT_login): %m");
+                return;
+        }
+
+        if (adt_set_user (adt_ah, pwent->pw_uid, pwent->pw_gid,
+            pwent->pw_uid, pwent->pw_gid, NULL, ADT_USER) != 0) {
+                syslog (LOG_AUTH | LOG_ALERT,
+                        "adt_set_user (ADT_login, %s): %m", pwent->pw_name);
+        }
+        if ((event = adt_alloc_event (adt_ah, ADT_login)) == 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 (pw_change == GDM_PW_TRUE) {
+                /* Also audit password change */
+                adt_free_event (event);
+                if ((event = adt_alloc_event (adt_ah, ADT_passwd)) == 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);
+        return (gpointer)adt_ah;
+}
+
+/*
+ * gdm_solaris_audit_fail_login - Audit failed login
+ *
+ *      Entry   username = NULL, or authenticated username to use.
+ *              hostname used if remote.
+ *              display_device = associated device.
+ *              pw_change == GDM_PW_FALSE,  if no password change requested.
+ *                           GDM_PW_TRUE,   if successful password change audit
+ *                                          required.
+ *                           GDM_PW_FAILED, if failed password change audit
+ *                                          required.
+ *              did_setcred == FALSE, process audit context is not established.
+ *                             TRUE,  process audit context established.
+ *              pam_error_code = PAM error code; reason for failure.
+ *              pam_error_string = pam_strerror output of PAM error code.
+ *
+ *      Exit    ADT_login (ADT_FAILURE) audit record written
+ *              pw_change == GDM_PW_TRUE, ADT_passwd (ADT_FAILURE) audit
+ *                           record written.
+ */
+void
+gdm_solaris_audit_fail_login (char *username,
+                              char *hostname,
+                              char *display_device,
+                              GdmPasswdChange pw_change,
+                              gboolean did_setcred,
+                              int pam_error_code,
+                              char *pam_error_string)
+{
+        adt_session_data_t  *ah;     /* Audit session handle     */
+        adt_event_data_t    *event;  /* Event to generate        */
+        adt_termid_t        *tid;    /* Terminal ID for failures */
+        struct passwd       *pwent;
+       
+        pwent = getpwnam (username);
+
+        if (did_setcred == TRUE) {
+                if (adt_start_session (&ah, NULL, ADT_USE_PROC_DATA) != 0) {
+                        syslog (LOG_AUTH | LOG_ALERT,
+                                "adt_start_session (ADT_login, ADT_FAILURE): %m");
+                        return;
+                }
+        } else {
+                if (adt_start_session (&ah, NULL, 0) != 0) {
+                        syslog (LOG_AUTH | LOG_ALERT,
+                                "adt_start_session (ADT_login, ADT_FAILURE): %m");
+                        return;
+                }
+
+                /* 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,
+                                  pwent ? pwent->pw_uid : ADT_NO_ATTRIB,
+                                  pwent ? pwent->pw_gid : ADT_NO_ATTRIB,
+                                  pwent ? pwent->pw_uid : ADT_NO_ATTRIB,
+                                  pwent ? pwent->pw_gid : ADT_NO_ATTRIB,
+                                  tid, ADT_NEW) != 0) {
+
+                        syslog (LOG_AUTH | LOG_ALERT,
+                                "adt_set_user (%s): %m",
+                                pwent ? pwent->pw_name : "ADT_NO_ATTRIB");
+                }
+        }
+
+        if ((event = adt_alloc_event (ah, ADT_login)) == 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 (pw_change != GDM_PW_FALSE) {
+                /* Also audit password change */
+                adt_free_event (event);
+
+                if ((event = adt_alloc_event (ah, ADT_passwd)) == NULL) {
+                        syslog (LOG_AUTH | LOG_ALERT,
+                                "adt_alloc_event (ADT_passwd): %m");
+                        goto done;
+                }
+
+                if (pw_change == GDM_PW_TRUE) {
+                        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 (pw_change == GDM_PW_FAILED) {
+                        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);
+}
+
+/*
+ * gdm_solaris_audit_logout - Audit user logout
+ *
+ *      Entry   adt_ah = audit session handle established by
+ *              audit_success_login ().
+ *
+ *      Exit    ADT_logout (ADT_SUCCESS) audit record written
+ *              process audit state reset.  (this process is reused for
+ *                      the next login.)
+ *              audit session adt_ah ended.
+ */
+void
+gdm_solaris_audit_logout (gpointer data)
+{
+        adt_session_data_t *adt_ah = NULL;  /* Audit session handle */
+        adt_event_data_t   *event;          /* Event to generate    */
+
+        adt_ah = (adt_session_data_t *)data;
+
+        if ((event = adt_alloc_event (adt_ah, ADT_logout)) == 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);
+}
+
+#endif /* HAVE_ADT */
--- /dev/null	2008-01-24 20:00:14.000000000 -0600
+++ daemon/gdm-audit-libaudit.c	2008-01-24 19:16:45.462567000 -0600
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * GDM - The GNOME Display Manager
+ * Copyright (C) 2007 Steve Grubb <sgrubb redhat com>
+ *
+ * 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 of the License, 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
+ */
+
+#include "config.h"
+
+#include <syslog.h>
+#include <security/pam_appl.h>
+#include <pwd.h>
+
+#include <fcntl.h>
+
+#include <glib.h>
+
+#include "gdm-audit.h"
+#include "gdm-audit-solaris.h"
+
+#ifdef HAVE_LIBAUDIT
+/**
+ * log_to_audit_system:
+ * @username:       Name of user
+ * @hostname:       Name of host machine
+ * @display_device: Name of display
+ * @success:        1 for success, 0 for failure
+ *
+ * Logs the success or failure of the login attempt with the linux kernel
+ * audit system. The intent is to capture failed events where the user
+ * fails authentication or otherwise is not permitted to login. There are
+ * many other places where pam could potentially fail and cause login to
+ * fail, but these are system failures rather than the signs of an account
+ * being hacked.
+ *
+ * Returns nothing.
+ */
+static void
+gdm_libaudit_log_to_audit_system (const char *username,
+                                  const char *hostname,
+                                  const char *display_device,
+                                  gboolean success)
+{
+        struct passwd *pw;
+        char buf[64];
+        int audit_fd;
+
+        audit_fd = audit_open ();
+        if (username)
+                pw = getpwnam (username);
+        else {
+                username = "unknown";
+                pw = NULL;
+        }
+        if (pw) {
+                snprintf (buf, sizeof (buf), "uid=%d", pw->pw_uid);
+                audit_log_user_message (audit_fd, AUDIT_USER_LOGIN,
+                                        buf, hostname, NULL, display_device, (int)success);
+        } else {
+                snprintf (buf, sizeof (buf), "acct=%s", username);
+                audit_log_user_message (audit_fd, AUDIT_USER_LOGIN,
+                                        buf, hostname, NULL, display_device, (int)success);
+        }
+        close (audit_fd);
+}
+
+#endif /* HAVE_LIBAUDIT */
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]