1 /* pam_audit.c -- Instrumentation code for Linux Auditing System */
3 /* (C) 2005-2006 Red Hat, Inc. -- Licensing details are in the COPYING
4 file accompanying the Linux-PAM source distribution.
7 Steve Grubb <sgrubb@redhat.com> */
11 #include "pam_private.h"
12 #include "pam_modutil_private.h"
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <arpa/inet.h>
24 #define PAMAUDIT_LOGGED 1
27 _pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type,
28 const char *message, int retval)
30 static int old_errno = -1;
34 snprintf(buf, sizeof(buf), "PAM:%s", message);
36 rc = audit_log_acct_message (audit_fd, type, NULL, buf,
37 (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?",
38 -1, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS );
40 /* libaudit sets errno to his own negative error code. This can be
41 an official errno number, but must not. It can also be a audit
42 internal error code. Which makes errno useless :-((. Try the
46 pamh->audit_state |= PAMAUDIT_LOGGED;
49 if (rc == -EPERM && getuid() != 0)
51 if (errno != old_errno) {
53 pam_syslog (pamh, LOG_CRIT, "audit_log_acct_message() failed: %m");
60 _pam_audit_open(pam_handle_t *pamh)
63 audit_fd = audit_open();
65 /* You get these error codes only when the kernel doesn't have
66 * audit compiled in. */
67 if (errno == EINVAL || errno == EPROTONOSUPPORT ||
68 errno == EAFNOSUPPORT)
71 /* this should only fail in case of extreme resource shortage,
72 * need to prevent login in that case for CAPP compliance.
74 pam_syslog(pamh, LOG_CRIT, "audit_open() failed: %m");
82 _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
88 if ((audit_fd=_pam_audit_open(pamh)) == -1) {
89 return PAM_SYSTEM_ERR;
90 } else if (audit_fd == -2) {
95 case PAM_AUTHENTICATE:
96 message = "authentication";
97 type = AUDIT_USER_AUTH;
99 case PAM_OPEN_SESSION:
100 message = "session_open";
101 type = AUDIT_USER_START;
103 case PAM_CLOSE_SESSION:
104 message = "session_close";
105 type = AUDIT_USER_END;
108 message = "accounting";
109 type = AUDIT_USER_ACCT;
112 message = "chauthtok";
113 type = AUDIT_USER_CHAUTHTOK;
117 if (flags & PAM_ESTABLISH_CRED)
118 type = AUDIT_CRED_ACQ;
119 else if ((flags & PAM_REINITIALIZE_CRED) || (flags & PAM_REFRESH_CRED))
120 type = AUDIT_CRED_REFR;
121 else if (flags & PAM_DELETE_CRED)
122 type = AUDIT_CRED_DISP;
124 type = AUDIT_USER_ERR;
126 case _PAM_ACTION_DONE:
127 message = "bad_ident";
128 type = AUDIT_USER_ERR;
132 type = AUDIT_USER_ERR;
133 pam_syslog(pamh, LOG_CRIT, "_pam_auditlog() should never get here");
134 retval = PAM_SYSTEM_ERR;
137 if (_pam_audit_writelog(pamh, audit_fd, type, message, retval) < 0)
138 retval = PAM_SYSTEM_ERR;
140 audit_close(audit_fd);
145 _pam_audit_end(pam_handle_t *pamh, int status UNUSED)
147 if (! (pamh->audit_state & PAMAUDIT_LOGGED)) {
148 /* PAM library is being shut down without any of the auditted
149 * stacks having been run. Assume that this is sshd faking
150 * things for an unknown user.
152 _pam_auditlog(pamh, _PAM_ACTION_DONE, PAM_USER_UNKNOWN, 0);
159 pam_modutil_audit_write(pam_handle_t *pamh, int type,
160 const char *message, int retval)
165 if ((audit_fd=_pam_audit_open(pamh)) == -1) {
166 return PAM_SYSTEM_ERR;
167 } else if (audit_fd == -2) {
171 rc = _pam_audit_writelog(pamh, audit_fd, type, message, retval);
173 audit_close(audit_fd);
175 return rc < 0 ? PAM_SYSTEM_ERR : PAM_SUCCESS;
179 int pam_modutil_audit_write(pam_handle_t *pamh UNUSED, int type UNUSED,
180 const char *message UNUSED, int retval UNUSED)
184 #endif /* HAVE_LIBAUDIT */