345 lines
9.3 KiB
Diff
345 lines
9.3 KiB
Diff
|
diff --git a/libpam/pam_account.c b/libpam/pam_account.c
|
||
|
index 572acc4..3a4fb1f 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 531746a..63a4ea5 100644
|
||
|
--- a/libpam/pam_audit.c
|
||
|
+++ b/libpam/pam_audit.c
|
||
|
@@ -28,14 +28,15 @@ _pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type,
|
||
|
const char *message, int retval)
|
||
|
{
|
||
|
static int old_errno = -1;
|
||
|
- int rc;
|
||
|
- char buf[32];
|
||
|
-
|
||
|
- snprintf(buf, sizeof(buf), "PAM:%s", message);
|
||
|
-
|
||
|
- 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 );
|
||
|
+ int rc = -ENOMEM;
|
||
|
+ char *buf = NULL;
|
||
|
+
|
||
|
+ if (asprintf(&buf, "PAM:%s", message) >= 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 +79,65 @@ _pam_audit_open(pam_handle_t *pamh)
|
||
|
return audit_fd;
|
||
|
}
|
||
|
|
||
|
+static char *
|
||
|
+_pam_list_grantors(struct handler *hlist, const char *message, int retval)
|
||
|
+{
|
||
|
+ char *buf;
|
||
|
+ char *list = NULL;
|
||
|
+
|
||
|
+ if (retval == PAM_SUCCESS) {
|
||
|
+ struct handler *h;
|
||
|
+ char *p = NULL;
|
||
|
+ size_t len = 0;
|
||
|
+
|
||
|
+ h = hlist;
|
||
|
+
|
||
|
+ while (h != NULL) {
|
||
|
+ if (h->grantor) {
|
||
|
+ len += strlen(h->mod_name) + 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ h = h->next;
|
||
|
+ }
|
||
|
+
|
||
|
+ list = malloc(len);
|
||
|
+ if (list == NULL) {
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ h = hlist;
|
||
|
+
|
||
|
+ while (h != NULL) {
|
||
|
+ if (h->grantor) {
|
||
|
+ if (p == NULL) {
|
||
|
+ p = list;
|
||
|
+ } else {
|
||
|
+ p = stpcpy(p, ",");
|
||
|
+ }
|
||
|
+
|
||
|
+ p = stpcpy(p, h->mod_name);
|
||
|
+ }
|
||
|
+
|
||
|
+ h = h->next;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (asprintf(&buf, "%s grantor=%s", message, list ? list : "?") < 0) {
|
||
|
+ free(list);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ free(list);
|
||
|
+ return buf;
|
||
|
+}
|
||
|
+
|
||
|
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 *buf = NULL;
|
||
|
|
||
|
if ((audit_fd=_pam_audit_open(pamh)) == -1) {
|
||
|
return PAM_SYSTEM_ERR;
|
||
|
@@ -134,9 +188,18 @@ _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)
|
||
|
+ buf = _pam_list_grantors(h, message, retval);
|
||
|
+ if (buf == NULL) {
|
||
|
+ /* allocation failure */
|
||
|
+ pam_syslog(pamh, LOG_CRIT, "_pam_list_grantors() failed: %m");
|
||
|
+ retval = PAM_SYSTEM_ERR;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (_pam_audit_writelog(pamh, audit_fd, type, buf ? buf : message, retval) < 0)
|
||
|
retval = PAM_SYSTEM_ERR;
|
||
|
|
||
|
+ free(buf);
|
||
|
+
|
||
|
audit_close(audit_fd);
|
||
|
return retval;
|
||
|
}
|
||
|
@@ -149,7 +212,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;
|
||
|
diff --git a/libpam/pam_auth.c b/libpam/pam_auth.c
|
||
|
index 5984fa5..1e7bc6e 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 eb52c82..ccfc372 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;
|
||
|
|
||
|
@@ -308,6 +314,14 @@ decision_made: /* by getting here we have made a decision */
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
+static void _pam_clear_grantors(struct handler *h)
|
||
|
+{
|
||
|
+ while (h != NULL) {
|
||
|
+ h->grantor = 0;
|
||
|
+ h = h->next;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* This function translates the module dispatch request into a pointer
|
||
|
* to the stack of modules that will actually be run. the
|
||
|
@@ -318,21 +332,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 +374,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 +408,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 +434,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 02714f7..e3f8ff6 100644
|
||
|
--- a/libpam/pam_handlers.c
|
||
|
+++ b/libpam/pam_handlers.c
|
||
|
@@ -889,6 +889,7 @@ int _pam_add_handler(pam_handle_t *pamh
|
||
|
(*handler_p)->argc = argc;
|
||
|
(*handler_p)->argv = argv; /* not a copy */
|
||
|
(*handler_p)->mod_name = extract_modulename(mod_path);
|
||
|
+ (*handler_p)->grantor = 0;
|
||
|
(*handler_p)->next = NULL;
|
||
|
|
||
|
/* some of the modules have a second calling function */
|
||
|
@@ -921,6 +922,7 @@ int _pam_add_handler(pam_handle_t *pamh
|
||
|
(*handler_p2)->argv = NULL; /* no arguments */
|
||
|
}
|
||
|
(*handler_p2)->mod_name = extract_modulename(mod_path);
|
||
|
+ (*handler_p2)->grantor = 0;
|
||
|
(*handler_p2)->next = NULL;
|
||
|
}
|
||
|
|
||
|
diff --git a/libpam/pam_password.c b/libpam/pam_password.c
|
||
|
index 75db5e5..592e01f 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 134dc72..d93283c 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 512153f..cb393c1 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;
|
||
|
|
||
|
}
|