0009-pam-audit.patch revision 5559
5559N/AFrom ff65f319d40fdc0d5f9d316b9c5d48d7cdebc6b6 Mon Sep 17 00:00:00 2001
5559N/AFrom: Alan Coopersmith <alan.coopersmith@oracle.com>
5559N/ADate: Sat, 2 Jan 2016 22:38:35 -0800
5559N/ASubject: [PATCH] pam audit
5559N/A
5398N/AFixes for bugs:
5398N/A15201967 SUNBT5015296 xscreensaver doesn't audit
5398N/A15326852 SUNBT6417168 xscreensaver loops while trying to unlock a session
5398N/A for a user whose password was expired
5398N/A15452882 SUNBT6654320 xscreensaver dies due to memory corruption
5398N/A15688159 SUNBT7008058 screensaver continues to accept old password for
5398N/A existing sessions after password changed
5398N/A
5398N/AAlso ensures that Xscreensaver on Solaris only uses PAM, and never attempts
5398N/Ato fallback to direct use of getpwent(), which isn't audited
5398N/A
5398N/AUpstream status unknown.
5398N/A---
5559N/A driver/Makefile.in | 2 +-
5559N/A driver/passwd-pam.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++-
5559N/A driver/passwd.c | 4 ++
5398N/A 3 files changed, 161 insertions(+), 3 deletions(-)
5398N/A
5398N/Adiff --git a/driver/Makefile.in b/driver/Makefile.in
5559N/Aindex a44e312..7aec6d9 100644
5398N/A--- a/driver/Makefile.in
5398N/A+++ b/driver/Makefile.in
5559N/A@@ -212,7 +212,7 @@ PDF2JPEG_LIBS = -framework Cocoa
5398N/A SAVER_LIBS = $(LIBS) $(X_LIBS) $(XMU_LIBS) @SAVER_LIBS@ \
5398N/A $(XDPMS_LIBS) $(XINERAMA_LIBS) $(GL_LIBS) $(X_PRE_LIBS) \
5398N/A -lXt -lX11 -lXext $(X_EXTRA_LIBS) \
5398N/A- $(PASSWD_LIBS)
5398N/A+ -lbsm $(PASSWD_LIBS)
5398N/A
5398N/A CMD_LIBS = $(LIBS) $(X_LIBS) \
5398N/A $(X_PRE_LIBS) -lX11 -lXext $(X_EXTRA_LIBS)
5398N/Adiff --git a/driver/passwd-pam.c b/driver/passwd-pam.c
5559N/Aindex 93c73f1..4d24ac3 100644
5398N/A--- a/driver/passwd-pam.c
5398N/A+++ b/driver/passwd-pam.c
5398N/A@@ -47,6 +47,8 @@
5398N/A
5398N/A #ifdef __sun
5398N/A # include <deflt.h>
5398N/A+# include <bsm/adt.h>
5398N/A+# include <bsm/adt_event.h>
5398N/A #endif
5398N/A
5398N/A extern char *blurb(void);
5398N/A@@ -81,6 +83,9 @@ extern void unblock_sigchld (void);
5398N/A #undef countof
5398N/A #define countof(x) (sizeof((x))/sizeof(*(x)))
5398N/A
5398N/A+static struct pam_response *reply = 0; /*making it global so we can free it */
5398N/A+static int replies = 0;
5398N/A+
5398N/A /* Some time between Red Hat 4.2 and 7.0, the words were transposed
5398N/A in the various PAM_x_CRED macro names. Yay!
5398N/A */
5398N/A@@ -178,6 +183,124 @@ Bool pam_priv_init (int argc, char **argv, Bool verbose_p);
5398N/A */
5398N/A static void *suns_pam_implementation_blows = 0;
5398N/A
5398N/A+#ifdef __sun
5398N/A+#include <syslog.h>
5398N/A+#include <bsm/adt.h>
5398N/A+#include <bsm/adt_event.h>
5398N/A+
5398N/A+static Bool audit_flag_global = True;
5398N/A+
5398N/A+/*
5398N/A+ * audit_lock - audit entry to screenlock
5398N/A+ *
5398N/A+ * Entry Process running with appropriate privilege to generate
5398N/A+ * audit records and real uid of the user.
5398N/A+ *
5398N/A+ * Exit ADT_screenlock audit record written.
5398N/A+ */
5398N/A+void
5398N/A+audit_lock(void)
5398N/A+{
5398N/A+ adt_session_data_t *ah; /* audit session handle */
5398N/A+ adt_event_data_t *event; /* audit event handle */
5398N/A+
5398N/A+ /* Audit start of screen lock -- equivalent to logout ;-) */
5398N/A+ if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT, "adt_start_session: %m");
5398N/A+ return;
5398N/A+ }
5398N/A+ if ((event = adt_alloc_event(ah, ADT_screenlock)) == NULL)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(ADT_screenlock): %m");
5398N/A+ } else {
5398N/A+ if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(ADT_screenlock): %m");
5398N/A+ }
5398N/A+ adt_free_event(event);
5398N/A+ }
5398N/A+ (void) adt_end_session(ah);
5398N/A+}
5398N/A+
5398N/A+/*
5398N/A+ * audit_unlock - audit screen unlock
5398N/A+ *
5398N/A+ * Entry Process running with appropriate privilege to generate
5398N/A+ * audit records and real uid of the user.
5398N/A+ * pam_status = PAM error code; reason for failure.
5398N/A+ *
5398N/A+ * Exit ADT_screenunlock audit record written.
5398N/A+ */
5398N/A+static void
5398N/A+audit_unlock(int pam_status)
5398N/A+{
5398N/A+ adt_session_data_t *ah; /* audit session handle */
5398N/A+ adt_event_data_t *event; /* audit event handle */
5398N/A+
5398N/A+ if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT,
5398N/A+ "adt_start_session(ADT_screenunlock): %m");
5398N/A+ return;
5398N/A+ }
5398N/A+ if ((event = adt_alloc_event(ah, ADT_screenunlock)) == NULL)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT,
5398N/A+ "adt_alloc_event(ADT_screenunlock): %m");
5398N/A+ } else {
5398N/A+ if (adt_put_event(event,
5398N/A+ pam_status == PAM_SUCCESS ? ADT_SUCCESS : ADT_FAILURE,
5398N/A+ pam_status == PAM_SUCCESS ? ADT_SUCCESS
5398N/A+ : ADT_FAIL_PAM + pam_status)
5398N/A+ != 0)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT,
5398N/A+ "adt_put_event(ADT_screenunlock(%s): %m",
5398N/A+ pam_strerror(NULL, pam_status));
5398N/A+ }
5398N/A+ adt_free_event(event);
5398N/A+ }
5398N/A+ (void) adt_end_session(ah);
5398N/A+}
5398N/A+
5398N/A+/*
5398N/A+ * audit_passwd - audit password change
5398N/A+ * Entry Process running with appropriate privilege to generate
5398N/A+ * audit records and real uid of the user.
5398N/A+ * pam_status = PAM error code; reason for failure.
5398N/A+ *
5398N/A+ * Exit ADT_passwd audit record written.
5398N/A+ */
5398N/A+static void
5398N/A+audit_passwd(int pam_status)
5398N/A+{
5398N/A+ adt_session_data_t *ah; /* audit session handle */
5398N/A+ adt_event_data_t *event; /* audit event handle */
5398N/A+
5398N/A+ if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT, "adt_start_session(ADT_passwd): %m");
5398N/A+ return;
5398N/A+ }
5398N/A+ if ((event = adt_alloc_event(ah, ADT_passwd)) == NULL)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT, "adt_alloc_event(ADT_passwd): %m");
5398N/A+ } else {
5398N/A+ if (adt_put_event(event,
5398N/A+ pam_status == PAM_SUCCESS ? ADT_SUCCESS : ADT_FAILURE,
5398N/A+ pam_status == PAM_SUCCESS ? ADT_SUCCESS
5398N/A+ : ADT_FAIL_PAM + pam_status)
5398N/A+ != 0)
5398N/A+ {
5398N/A+ syslog(LOG_AUTH | LOG_ALERT, "adt_put_event(ADT_passwd(%s): %m",
5398N/A+ pam_strerror(NULL, pam_status));
5398N/A+ }
5398N/A+ adt_free_event(event);
5398N/A+ }
5398N/A+ (void) adt_end_session(ah);
5398N/A+}
5398N/A+#endif /* sun */
5398N/A
5398N/A /**
5398N/A * This function is the PAM conversation driver. It conducts a full
5398N/A@@ -231,6 +354,12 @@ pam_try_unlock(saver_info *si, Bool verbose_p,
5398N/A fprintf (stderr, "%s: pam_start (\"%s\", \"%s\", ...) ==> %d (%s)\n",
5398N/A blurb(), service, si->user,
5398N/A status, PAM_STRERROR (pamh, status));
5398N/A+
5398N/A+#ifdef __sun
5398N/A+ if (audit_flag_global) /* We want one audit lock log per lock */
5398N/A+ audit_lock ();
5398N/A+#endif /**sun*/
5398N/A+
5398N/A if (status != PAM_SUCCESS) goto DONE;
5398N/A
5398N/A #ifdef __sun
5398N/A@@ -307,6 +436,14 @@ pam_try_unlock(saver_info *si, Bool verbose_p,
5398N/A # endif /* HAVE_SIGTIMEDWAIT */
5398N/A unblock_sigchld();
5398N/A
5398N/A+#ifdef __sun
5398N/A+ audit_unlock(pam_auth_status);
5398N/A+ if (pam_auth_status == PAM_SUCCESS)
5398N/A+ audit_flag_global = True;
5398N/A+ else
5398N/A+ audit_flag_global = False;
5398N/A+#endif /*sun*/
5398N/A+
5398N/A #ifdef HAVE_XSCREENSAVER_LOCK
5398N/A /* Send status message to unlock dialog */
5398N/A if (pam_auth_status == PAM_SUCCESS)
5398N/A@@ -354,7 +491,14 @@ pam_try_unlock(saver_info *si, Bool verbose_p,
5398N/A write_to_child (si, "ul_acct_ok", PAM_STRERROR(pamh, acct_rc));
5398N/A }
5398N/A else
5398N/A- write_to_child (si, "ul_acct_fail", PAM_STRERROR(pamh, acct_rc));
5398N/A+ {
5398N/A+#ifdef __sun
5398N/A+ /* Only in failure of pam_acct_mgmt case we call audit */
5398N/A+ audit_unlock (acct_rc);
5398N/A+#endif /*sun*/
5398N/A+
5398N/A+ write_to_child (si, "ul_acct_fail", PAM_STRERROR(pamh, acct_rc));
5398N/A+ }
5398N/A if (verbose_p)
5398N/A sleep (1);
5398N/A #endif
5559N/A@@ -384,6 +528,10 @@ pam_try_unlock(saver_info *si, Bool verbose_p,
5398N/A fprintf (stderr, "%s: pam_chauthtok (...) ==> %d (%s)\n",
5398N/A blurb(), chauth_rc, PAM_STRERROR(pamh, chauth_rc));
5398N/A
5398N/A+#ifdef __sun
5398N/A+ audit_passwd (chauth_rc);
5398N/A+#endif /* sun */
5398N/A+
5398N/A if (chauth_rc != PAM_SUCCESS)
5398N/A {
5398N/A pam_auth_status = chauth_rc;
5559N/A@@ -433,7 +581,13 @@ pam_try_unlock(saver_info *si, Bool verbose_p,
5398N/A write_to_child (si, "ul_setcred_ok", PAM_STRERROR(pamh, setcred_rc));
5398N/A }
5398N/A else
5398N/A- write_to_child (si, "ul_setcred_fail", PAM_STRERROR(pamh, setcred_rc));
5398N/A+ {
5398N/A+#ifdef __sun
5398N/A+ /* Only in failure of pam_setcred() case we call audit. */
5398N/A+ audit_unlock (setcred_rc);
5398N/A+#endif /*sun*/
5398N/A+ write_to_child (si, "ul_setcred_fail", PAM_STRERROR(pamh, setcred_rc));
5398N/A+ }
5398N/A if (verbose_p)
5398N/A sleep (1);
5398N/A #endif
5398N/Adiff --git a/driver/passwd.c b/driver/passwd.c
5559N/Aindex 0618642..350dc4d 100644
5398N/A--- a/driver/passwd.c
5398N/A+++ b/driver/passwd.c
5559N/A@@ -81,9 +81,11 @@ extern void pam_try_unlock (saver_info *si, Bool verbose_p,
5398N/A extern Bool ext_priv_init (int argc, char **argv, Bool verbose_p);
5398N/A extern Bool ext_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
5398N/A #endif
5398N/A+#ifndef __sun /* Only use PAM on Solaris, not direct getpwent */
5398N/A extern Bool pwent_lock_init (int argc, char **argv, Bool verbose_p);
5398N/A extern Bool pwent_priv_init (int argc, char **argv, Bool verbose_p);
5398N/A extern Bool pwent_passwd_valid_p (const char *typed_passwd, Bool verbose_p);
5398N/A+#endif
5398N/A
5398N/A Bool lock_priv_init (int argc, char **argv, Bool verbose_p);
5398N/A Bool lock_init (int argc, char **argv, Bool verbose_p);
5559N/A@@ -107,8 +109,10 @@ struct auth_methods methods[] = {
5398N/A { "external", 0, ext_priv_init, ext_passwd_valid_p, 0,
5398N/A False, False },
5398N/A # endif
5398N/A+# ifndef __sun /* Only use PAM on Solaris, not direct getpwent */
5398N/A { "normal", pwent_lock_init, pwent_priv_init, pwent_passwd_valid_p, 0,
5398N/A False, False }
5398N/A+# endif
5398N/A };
5398N/A
5398N/A
5559N/A--
5559N/A2.6.1
5398N/A