summaryrefslogtreecommitdiff
path: root/libpam
diff options
context:
space:
mode:
Diffstat (limited to 'libpam')
-rw-r--r--libpam/pam_account.c4
-rw-r--r--libpam/pam_audit.c84
-rw-r--r--libpam/pam_auth.c8
-rw-r--r--libpam/pam_dispatch.c41
-rw-r--r--libpam/pam_handlers.c14
-rw-r--r--libpam/pam_password.c4
-rw-r--r--libpam/pam_private.h3
-rw-r--r--libpam/pam_session.c7
8 files changed, 119 insertions, 46 deletions
diff --git a/libpam/pam_account.c b/libpam/pam_account.c
index 572acc47..3a4fb1fc 100644
--- a/libpam/pam_account.c
+++ b/libpam/pam_account.c
@@ -19,9 +19,5 @@ int pam_acct_mgmt(pam_handle_t *pamh, int flags)
retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT);
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_ACCOUNT, retval, flags);
-#endif
-
return retval;
}
diff --git a/libpam/pam_audit.c b/libpam/pam_audit.c
index 531746ab..24fb799a 100644
--- a/libpam/pam_audit.c
+++ b/libpam/pam_audit.c
@@ -6,12 +6,12 @@
Authors:
Steve Grubb <sgrubb@redhat.com> */
-#include <stdio.h>
-#include <syslog.h>
#include "pam_private.h"
#include "pam_modutil_private.h"
#ifdef HAVE_LIBAUDIT
+#include <stdio.h>
+#include <syslog.h>
#include <libaudit.h>
#include <pwd.h>
#include <netdb.h>
@@ -25,17 +25,24 @@
static int
_pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type,
- const char *message, int retval)
+ const char *message, const char *grantors, int retval)
{
static int old_errno = -1;
- int rc;
- char buf[32];
+ int rc = -ENOMEM;
+ char *buf;
+ const char *grantors_field = " grantors=";
- snprintf(buf, sizeof(buf), "PAM:%s", message);
+ if (grantors == NULL) {
+ grantors = "";
+ grantors_field = "";
+ }
- rc = audit_log_acct_message (audit_fd, type, NULL, buf,
- (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?",
- -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS );
+ if (asprintf(&buf, "PAM:%s%s%s", message, grantors_field, grantors) >= 0) {
+ rc = audit_log_acct_message(audit_fd, type, NULL, buf,
+ (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?",
+ -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS);
+ free(buf);
+ }
/* libaudit sets errno to his own negative error code. This can be
an official errno number, but must not. It can also be a audit
@@ -78,12 +85,54 @@ _pam_audit_open(pam_handle_t *pamh)
return audit_fd;
}
+static int
+_pam_list_grantors(struct handler *hlist, int retval, char **list)
+{
+ *list = NULL;
+
+ if (retval == PAM_SUCCESS) {
+ struct handler *h;
+ char *p = NULL;
+ size_t len = 0;
+
+ for (h = hlist; h != NULL; h = h->next) {
+ if (h->grantor) {
+ len += strlen(h->mod_name) + 1;
+ }
+ }
+
+ if (len == 0) {
+ return 0;
+ }
+
+ *list = malloc(len);
+ if (*list == NULL) {
+ return -1;
+ }
+
+ for (h = hlist; h != NULL; h = h->next) {
+ if (h->grantor) {
+ if (p == NULL) {
+ p = *list;
+ } else {
+ p = stpcpy(p, ",");
+ }
+
+ p = stpcpy(p, h->mod_name);
+ }
+ }
+ }
+
+ return 0;
+}
+
int
-_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
+_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h)
{
const char *message;
int type;
int audit_fd;
+ char *grantors;
if ((audit_fd=_pam_audit_open(pamh)) == -1) {
return PAM_SYSTEM_ERR;
@@ -134,8 +183,17 @@ _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
retval = PAM_SYSTEM_ERR;
}
- if (_pam_audit_writelog(pamh, audit_fd, type, message, retval) < 0)
+ if (_pam_list_grantors(h, retval, &grantors) < 0) {
+ /* allocation failure */
+ pam_syslog(pamh, LOG_CRIT, "_pam_list_grantors() failed: %m");
retval = PAM_SYSTEM_ERR;
+ }
+
+ if (_pam_audit_writelog(pamh, audit_fd, type, message,
+ grantors ? grantors : "?", retval) < 0)
+ retval = PAM_SYSTEM_ERR;
+
+ free(grantors);
audit_close(audit_fd);
return retval;
@@ -149,7 +207,7 @@ _pam_audit_end(pam_handle_t *pamh, int status UNUSED)
* stacks having been run. Assume that this is sshd faking
* things for an unknown user.
*/
- _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0);
+ _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0, NULL);
}
return 0;
@@ -168,7 +226,7 @@ pam_modutil_audit_write(pam_handle_t *pamh, int type,
return retval;
}
- rc = _pam_audit_writelog(pamh, audit_fd, type, message, retval);
+ rc = _pam_audit_writelog(pamh, audit_fd, type, message, NULL, retval);
audit_close(audit_fd);
diff --git a/libpam/pam_auth.c b/libpam/pam_auth.c
index 5984fa59..1e7bc6e7 100644
--- a/libpam/pam_auth.c
+++ b/libpam/pam_auth.c
@@ -45,10 +45,6 @@ int pam_authenticate(pam_handle_t *pamh, int flags)
prelude_send_alert(pamh, retval);
#endif
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_AUTHENTICATE, retval, flags);
-#endif
-
return retval;
}
@@ -71,10 +67,6 @@ int pam_setcred(pam_handle_t *pamh, int flags)
retval = _pam_dispatch(pamh, flags, PAM_SETCRED);
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_SETCRED, retval, flags);
-#endif
-
D(("pam_setcred exit"));
return retval;
diff --git a/libpam/pam_dispatch.c b/libpam/pam_dispatch.c
index eb52c824..cf632e8e 100644
--- a/libpam/pam_dispatch.c
+++ b/libpam/pam_dispatch.c
@@ -217,8 +217,14 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
status = retval;
}
}
- if ( impression == _PAM_POSITIVE && action == _PAM_ACTION_DONE ) {
- goto decision_made;
+ if ( impression == _PAM_POSITIVE ) {
+ if ( retval == PAM_SUCCESS ) {
+ h->grantor = 1;
+ }
+
+ if ( action == _PAM_ACTION_DONE ) {
+ goto decision_made;
+ }
}
break;
@@ -262,6 +268,9 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
|| (impression == _PAM_POSITIVE
&& status == PAM_SUCCESS) ) {
if ( retval != PAM_IGNORE || cached_retval == retval ) {
+ if ( impression == _PAM_UNDEF && retval == PAM_SUCCESS ) {
+ h->grantor = 1;
+ }
impression = _PAM_POSITIVE;
status = retval;
}
@@ -308,6 +317,13 @@ decision_made: /* by getting here we have made a decision */
return status;
}
+static void _pam_clear_grantors(struct handler *h)
+{
+ for (; h != NULL; h = h->next) {
+ h->grantor = 0;
+ }
+}
+
/*
* This function translates the module dispatch request into a pointer
* to the stack of modules that will actually be run. the
@@ -318,21 +334,21 @@ decision_made: /* by getting here we have made a decision */
int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
{
struct handler *h = NULL;
- int retval, use_cached_chain;
+ int retval = PAM_SYSTEM_ERR, use_cached_chain;
_pam_boolean resumed;
IF_NO_PAMH("_pam_dispatch", pamh, PAM_SYSTEM_ERR);
if (__PAM_FROM_MODULE(pamh)) {
D(("called from a module!?"));
- return PAM_SYSTEM_ERR;
+ goto end;
}
/* Load all modules, resolve all symbols */
if ((retval = _pam_init_handlers(pamh)) != PAM_SUCCESS) {
pam_syslog(pamh, LOG_ERR, "unable to dispatch function");
- return retval;
+ goto end;
}
use_cached_chain = _PAM_PLEASE_FREEZE;
@@ -360,7 +376,8 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
break;
default:
pam_syslog(pamh, LOG_ERR, "undefined fn choice; %d", choice);
- return PAM_ABORT;
+ retval = PAM_ABORT;
+ goto end;
}
if (h == NULL) { /* there was no handlers.conf... entry; will use
@@ -393,11 +410,13 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
pam_syslog(pamh, LOG_ERR,
"application failed to re-exec stack [%d:%d]",
pamh->former.choice, choice);
- return PAM_ABORT;
+ retval = PAM_ABORT;
+ goto end;
}
resumed = PAM_TRUE;
} else {
resumed = PAM_FALSE;
+ _pam_clear_grantors(h);
}
__PAM_TO_MODULE(pamh);
@@ -417,5 +436,13 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
pamh->former.choice = PAM_NOT_STACKED;
}
+end:
+
+#ifdef HAVE_LIBAUDIT
+ if (choice != PAM_CHAUTHTOK || flags & PAM_UPDATE_AUTHTOK || retval != PAM_SUCCESS) {
+ retval = _pam_auditlog(pamh, choice, retval, flags, h);
+ }
+#endif
+
return retval;
}
diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c
index 02714f78..df3a1d91 100644
--- a/libpam/pam_handlers.c
+++ b/libpam/pam_handlers.c
@@ -611,6 +611,12 @@ extract_modulename(const char *mod_path)
if (dot)
*dot = '\0';
+ if (*retval == '\0' || strcmp(retval, "?") == 0) {
+ /* do not allow empty module name or "?" to avoid confusing audit trail */
+ _pam_drop(retval);
+ return NULL;
+ }
+
return retval;
}
@@ -888,7 +894,9 @@ int _pam_add_handler(pam_handle_t *pamh
(*handler_p)->cached_retval_p = &((*handler_p)->cached_retval);
(*handler_p)->argc = argc;
(*handler_p)->argv = argv; /* not a copy */
- (*handler_p)->mod_name = extract_modulename(mod_path);
+ if (((*handler_p)->mod_name = extract_modulename(mod_path)) == NULL)
+ return PAM_ABORT;
+ (*handler_p)->grantor = 0;
(*handler_p)->next = NULL;
/* some of the modules have a second calling function */
@@ -920,7 +928,9 @@ int _pam_add_handler(pam_handle_t *pamh
} else {
(*handler_p2)->argv = NULL; /* no arguments */
}
- (*handler_p2)->mod_name = extract_modulename(mod_path);
+ if (((*handler_p2)->mod_name = extract_modulename(mod_path)) == NULL)
+ return PAM_ABORT;
+ (*handler_p2)->grantor = 0;
(*handler_p2)->next = NULL;
}
diff --git a/libpam/pam_password.c b/libpam/pam_password.c
index 75db5e50..592e01fb 100644
--- a/libpam/pam_password.c
+++ b/libpam/pam_password.c
@@ -57,9 +57,5 @@ int pam_chauthtok(pam_handle_t *pamh, int flags)
D(("will resume when ready", retval));
}
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_CHAUTHTOK, retval, flags);
-#endif
-
return retval;
}
diff --git a/libpam/pam_private.h b/libpam/pam_private.h
index 134dc726..d93283ce 100644
--- a/libpam/pam_private.h
+++ b/libpam/pam_private.h
@@ -55,6 +55,7 @@ struct handler {
struct handler *next;
char *mod_name;
int stack_level;
+ int grantor;
};
#define PAM_HT_MODULE 0
@@ -316,7 +317,7 @@ if ((pamh) == NULL) { \
do { (pamh)->caller_is = _PAM_CALLED_FROM_APP; } while (0)
#ifdef HAVE_LIBAUDIT
-extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags);
+extern int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h);
extern int _pam_audit_end(pam_handle_t *pamh, int pam_status);
#endif
diff --git a/libpam/pam_session.c b/libpam/pam_session.c
index 512153f2..cb393c1a 100644
--- a/libpam/pam_session.c
+++ b/libpam/pam_session.c
@@ -22,9 +22,6 @@ int pam_open_session(pam_handle_t *pamh, int flags)
}
retval = _pam_dispatch(pamh, flags, PAM_OPEN_SESSION);
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_OPEN_SESSION, retval, flags);
-#endif
return retval;
}
@@ -43,10 +40,6 @@ int pam_close_session(pam_handle_t *pamh, int flags)
retval = _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION);
-#ifdef HAVE_LIBAUDIT
- retval = _pam_auditlog(pamh, PAM_CLOSE_SESSION, retval, flags);
-#endif
-
return retval;
}