]> granicus.if.org Git - linux-pam/blobdiff - modules/pam_tally2/pam_tally2.c
pam_tally2: Optionally log the tally count when checking.
[linux-pam] / modules / pam_tally2 / pam_tally2.c
index d3d6779a3d4ef055482df1c4ab9ecdada41f5fbd..e513f64c9c7f73d08f54b4a206ebc7c67b0fc7bf 100644 (file)
@@ -124,6 +124,7 @@ struct tally_options {
 #define OPT_AUDIT                       0100
 #define OPT_NOLOGNOTICE                 0400
 #define OPT_SERIALIZE                  01000
+#define OPT_DEBUG                      02000
 
 #define MAX_LOCK_WAITING_TIME 10
 
@@ -196,6 +197,9 @@ tally_parse_args(pam_handle_t *pamh, struct tally_options *opts,
       else if ( ! strcmp( *argv, "serialize" ) ) {
         opts->ctrl |= OPT_SERIALIZE;
       }
+      else if ( ! strcmp( *argv, "debug" ) ) {
+        opts->ctrl |= OPT_DEBUG;
+      }
       else if ( ! strcmp( *argv, "even_deny_root_account" ) ||
                 ! strcmp( *argv, "even_deny_root" ) ) {
        log_phase_no_auth(pamh, phase, *argv);
@@ -451,11 +455,8 @@ skip_open:
        alarm(oldalarm);
     }
 
-    if (fileinfo.st_size < (off_t)(uid+1)*(off_t)sizeof(*tally)) {
-       memset(tally, 0, sizeof(*tally));
-    } else if (pam_modutil_read(*tfile, void_tally, sizeof(*tally)) != sizeof(*tally)) {
+    if (pam_modutil_read(*tfile, void_tally, sizeof(*tally)) != sizeof(*tally)) {
        memset(tally, 0, sizeof(*tally));
-       /* Shouldn't happen */
     }
 
     tally->fail_line[sizeof(tally->fail_line)-1] = '\0';
@@ -506,9 +507,11 @@ tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid,
             struct tallylog *tally)
 {
     int rv = PAM_SUCCESS;
+    int loglevel = LOG_DEBUG;
 #ifdef HAVE_LIBAUDIT
     char buf[64];
     int audit_fd = -1;
+    const void *rhost = NULL, *tty = NULL;
 #endif
 
     if ((opts->ctrl & OPT_MAGIC_ROOT) && getuid() == 0) {
@@ -521,6 +524,8 @@ tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid,
     if ((audit_fd < 0) && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
                             errno == EAFNOSUPPORT))
          return PAM_SYSTEM_ERR;
+    (void)pam_get_item(pamh, PAM_TTY, &tty);
+    (void)pam_get_item(pamh, PAM_RHOST, &rhost);
 #endif
     if (opts->deny != 0 &&                        /* deny==0 means no deny        */
         tally->fail_cnt > opts->deny &&           /* tally>deny means exceeded    */
@@ -530,7 +535,7 @@ tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid,
             /* First say that max number was hit. */
             snprintf(buf, sizeof(buf), "pam_tally2 uid=%u ", uid);
             audit_log_user_message(audit_fd, AUDIT_ANOM_LOGIN_FAILURES, buf,
-                                   NULL, NULL, NULL, 1);
+                                   rhost, NULL, tty, 1);
         }
 #endif
         if (uid) {
@@ -541,7 +546,7 @@ tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid,
 #ifdef HAVE_LIBAUDIT
                     snprintf(buf, sizeof(buf), "pam_tally2 uid=%u ", uid);
                     audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf,
-                                   NULL, NULL, NULL, 1);
+                                   rhost, NULL, tty, 1);
 #endif
                    rv = PAM_SUCCESS;
                    goto cleanup;
@@ -555,7 +560,7 @@ tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid,
 #ifdef HAVE_LIBAUDIT
                     snprintf(buf, sizeof(buf), "pam_tally2 uid=%u ", uid);
                     audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf,
-                                   NULL, NULL, NULL, 1);
+                                   rhost, NULL, tty, 1);
 #endif
                    rv = PAM_SUCCESS;
                    goto cleanup;
@@ -567,7 +572,7 @@ tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid,
         if (tally->fail_cnt == opts->deny+1) {
             /* First say that max number was hit. */
             audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_LOCK, buf,
-                                   NULL, NULL, NULL, 1);
+                                   rhost, NULL, tty, 1);
         }
 #endif
 
@@ -575,11 +580,7 @@ tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid,
             pam_info(pamh, _("Account locked due to %u failed logins"),
                    (unsigned int)tally->fail_cnt);
         }
-       if (!(opts->ctrl & OPT_NOLOGNOTICE)) {
-            pam_syslog(pamh, LOG_NOTICE,
-                   "user %s (%lu) tally %hu, deny %hu",
-                  user, (unsigned long)uid, tally->fail_cnt, opts->deny);
-       }
+       loglevel = LOG_NOTICE;
         rv = PAM_AUTH_ERR;                 /* Only unconditional failure   */
         goto cleanup;
     }
@@ -609,6 +610,11 @@ tally_check (tally_t oldcnt, time_t oldtime, pam_handle_t *pamh, uid_t uid,
     }
 
 cleanup:
+    if (!(opts->ctrl & OPT_NOLOGNOTICE) && (loglevel != LOG_DEBUG || opts->ctrl & OPT_DEBUG)) {
+        pam_syslog(pamh, loglevel,
+            "user %s (%lu) tally %hu, deny %hu",
+            user, (unsigned long)uid, tally->fail_cnt, opts->deny);
+    }
 #ifdef HAVE_LIBAUDIT
     if (audit_fd != -1) {
         close(audit_fd);
@@ -996,7 +1002,7 @@ main( int argc UNUSED, char **argv )
         int audit_fd = audit_open();
         snprintf(buf, sizeof(buf), "pam_tally2 uid=%u reset=%hu", uid, cline_reset);
         audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
-                buf, NULL, NULL, NULL, 1);
+                buf, NULL, NULL, ttyname(STDIN_FILENO), 1);
         if (audit_fd >=0)
                 close(audit_fd);
 #endif
@@ -1041,7 +1047,7 @@ main( int argc UNUSED, char **argv )
       int audit_fd = audit_open();
       snprintf(buf, sizeof(buf), "pam_tally2 uid=all reset=0");
       audit_log_user_message(audit_fd, AUDIT_USER_ACCT,
-              buf, NULL, NULL, NULL, 1);
+              buf, NULL, NULL, ttyname(STDIN_FILENO), 1);
       if (audit_fd >=0)
               close(audit_fd);
 #endif