From 210f1644ea137a63aefda9e44d0c9347797b8ef7 Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Fri, 14 Jun 2019 09:03:13 +0100
Subject: [PATCH] Add a 'quiet_fail' option to pam_sso to suppress auth failure
 logs

Validation error details are also moved behind the 'debug' option,
in order to reduce noise.
---
 src/pam_sso/pam_sso.c | 40 ++++++++++++++++++++++++++++++++--------
 src/pam_sso/pam_sso.h |  1 +
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/pam_sso/pam_sso.c b/src/pam_sso/pam_sso.c
index 9cd20e7..5c7588d 100644
--- a/src/pam_sso/pam_sso.c
+++ b/src/pam_sso/pam_sso.c
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <syslog.h>
 #include <unistd.h>
+#include <errno.h>
 #include <fcntl.h>
 #include "pam_sso.h"
 
@@ -53,13 +54,15 @@ static void free_config(struct pam_sso_config *cfg) {
   }
 }
 
-static void parse_config(struct pam_sso_config *cfg, int argc, const char **argv) {
+static int parse_config(pam_handle_t *pamh, struct pam_sso_config *cfg, int argc, const char **argv) {
   for (const char **argp = argv; argc--; argp++) {
     const char *arg = *argp;
     if (!strcmp(arg, "debug")) {
       cfg->debug = 1;
     } else if (!strcmp(arg, "use_first_pass")) {
       cfg->use_first_pass = 1;
+    } else if (!strcmp(arg, "quiet_fail")) {
+      cfg->quiet_fail = 1;
     } else if (!strncmp(arg, "login_server=", 12)) {
       cfg->login_server = arg + 12;
     } else if (!strncmp(arg, "domain=", 7)) {
@@ -72,16 +75,27 @@ static void parse_config(struct pam_sso_config *cfg, int argc, const char **argv
       } else {
         cfg->required_groups = (const char **)realloc(cfg->required_groups, sizeof(char*)*(cfg->n_required_groups + 2));
       }
+      if (cfg->required_groups == NULL) {
+        pam_syslog(pamh, LOG_ERR, "out of memory");
+        return -1;
+      }
       cfg->required_groups[cfg->n_required_groups] = arg + 6;
       cfg->required_groups[cfg->n_required_groups + 1] = NULL;
       cfg->n_required_groups++;
     } else if (!strncmp(arg, "key=", 4)) {
       unsigned char *pk = (unsigned char *)malloc(SSO_PUBLIC_KEY_SIZE);
-      if (read_from_file(arg + 4, pk, SSO_PUBLIC_KEY_SIZE) == 0) {
-        cfg->public_key = pk;
+      if (pk == NULL) {
+        pam_syslog(pamh, LOG_ERR, "out of memory");
+        return -1;
+      }        
+      if (read_from_file(arg + 4, pk, SSO_PUBLIC_KEY_SIZE) < 0) {
+        pam_syslog(pamh, LOG_ERR, "error loading public key file: %s", strerror(errno));
+        return -1;
       }
+      cfg->public_key = pk;
     }
   }
+  return 0;
 }
 
 static int authenticate(pam_handle_t *pamh,
@@ -99,7 +113,9 @@ static int authenticate(pam_handle_t *pamh,
 
   r = sso_ticket_open(&t, ticket_string, cfg->public_key);
   if (r != SSO_OK) {
-    pam_syslog(pamh, LOG_INFO, "error decoding ticket: %s", sso_strerror(r));
+    if (cfg->debug) {
+      pam_syslog(pamh, LOG_INFO, "error decoding ticket: %s", sso_strerror(r));
+    }
     return 0;
   }
 
@@ -110,10 +126,14 @@ static int authenticate(pam_handle_t *pamh,
     if (!strcmp(t->user, username)) {
       retval = 1;
     } else {
-      pam_syslog(pamh, LOG_INFO, "user in ticket does not match request (%s vs %s)", t->user, username);
+      if (cfg->debug) {
+        pam_syslog(pamh, LOG_INFO, "user in ticket does not match request (%s vs %s)", t->user, username);
+      }
     }
   } else {
-    pam_syslog(pamh, LOG_INFO, "error validating ticket: %s", sso_strerror(r));
+    if (cfg->debug) {
+      pam_syslog(pamh, LOG_INFO, "error validating ticket: %s", sso_strerror(r));
+    }
   }
 
   sso_ticket_free(t);
@@ -126,7 +146,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
   const char *user = NULL, *password = NULL;
 
   // Parse configuration.
-  parse_config(&cfg, argc, argv);
+  if (parse_config(pamh, &cfg, argc, argv) < 0) {
+    return PAM_SERVICE_ERR;
+  }
 
   // Retrieve user from PAM.
   if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
@@ -162,7 +184,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
 
   // Authenticate.
   if (!authenticate(pamh, &cfg, user, password)) {
-    pam_syslog(pamh, LOG_ERR, "authentication failed");
+    if (!cfg.quiet_fail) {
+      pam_syslog(pamh, LOG_ERR, "authentication failed");
+    }
     goto error;
   }
 
diff --git a/src/pam_sso/pam_sso.h b/src/pam_sso/pam_sso.h
index 42f6ec1..ccdaee5 100644
--- a/src/pam_sso/pam_sso.h
+++ b/src/pam_sso/pam_sso.h
@@ -67,6 +67,7 @@ struct pam_sso_config {
   int n_required_groups;
   int debug;
   int use_first_pass;
+  int quiet_fail;
 };
 
 /**
-- 
GitLab