2
* Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
3
* Copyright (c) 2009 Christian S.J. Peron
5
* Permission to use, copy, modify, and distribute this software for any
6
* purpose with or without fee is hereby granted, provided that the above
7
* copyright notice and this permission notice appear in all copies.
9
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
#include <sys/types.h>
22
#include <bsm/audit.h>
23
#include <bsm/libbsm.h>
24
#include <bsm/audit_uevents.h>
33
#include "bsm_audit.h"
36
* Solaris auditon() returns EINVAL if BSM audit not configured.
37
* OpenBSM returns ENOSYS for unimplemented options.
40
# define AUDIT_NOT_CONFIGURED EINVAL
42
# define AUDIT_NOT_CONFIGURED ENOSYS
45
void log_error(int flags, const char *fmt, ...) __attribute__((__noreturn__));
48
audit_sudo_selected(int sf)
50
auditinfo_addr_t ainfo_addr;
55
if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) {
56
if (errno == ENOSYS) {
57
if (getaudit(&ainfo) < 0)
58
log_error(0, _("getaudit: failed"));
59
mask = &ainfo.ai_mask;
61
log_error(0, _("getaudit: failed"));
63
mask = &ainfo_addr.ai_mask;
64
sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE;
65
rc = au_preselect(AUE_sudo, mask, sorf, AU_PRS_REREAD);
70
bsm_audit_success(char **exec_args)
72
auditinfo_addr_t ainfo_addr;
82
* If we are not auditing, don't cut an audit record; just return.
84
if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
85
if (errno == AUDIT_NOT_CONFIGURED)
87
log_error(0, _("Could not determine audit condition"));
89
if (au_cond == AUC_NOAUDIT)
92
* Check to see if the preselection masks are interested in seeing
95
if (!audit_sudo_selected(0))
97
if (getauid(&auid) < 0)
98
log_error(0, _("getauid failed"));
99
if ((aufd = au_open()) == -1)
100
log_error(0, _("au_open: failed"));
101
if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
102
tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
103
getuid(), pid, pid, &ainfo_addr.ai_termid);
104
} else if (errno == ENOSYS) {
106
* NB: We should probably watch out for ERANGE here.
108
if (getaudit(&ainfo) < 0)
109
log_error(0, _("getaudit: failed"));
110
tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
111
getuid(), pid, pid, &ainfo.ai_termid);
113
log_error(0, _("getaudit: failed"));
115
log_error(0, _("au_to_subject: failed"));
117
tok = au_to_exec_args(exec_args);
119
log_error(0, _("au_to_exec_args: failed"));
121
tok = au_to_return32(0, 0);
123
log_error(0, _("au_to_return32: failed"));
125
if (au_close(aufd, 1, AUE_sudo) == -1)
126
log_error(0, _("unable to commit audit record"));
130
bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap)
132
auditinfo_addr_t ainfo_addr;
143
* If we are not auditing, don't cut an audit record; just return.
145
if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
146
if (errno == AUDIT_NOT_CONFIGURED)
148
log_error(0, _("Could not determine audit condition"));
150
if (au_cond == AUC_NOAUDIT)
152
if (!audit_sudo_selected(1))
154
if (getauid(&auid) < 0)
155
log_error(0, _("getauid: failed"));
156
if ((aufd = au_open()) == -1)
157
log_error(0, _("au_open: failed"));
158
if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
159
tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
160
getuid(), pid, pid, &ainfo_addr.ai_termid);
161
} else if (errno == ENOSYS) {
162
if (getaudit(&ainfo) < 0)
163
log_error(0, _("getaudit: failed"));
164
tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
165
getuid(), pid, pid, &ainfo.ai_termid);
167
log_error(0, _("getaudit: failed"));
169
log_error(0, _("au_to_subject: failed"));
171
tok = au_to_exec_args(exec_args);
173
log_error(0, _("au_to_exec_args: failed"));
175
(void) vsnprintf(text, sizeof(text), fmt, ap);
176
tok = au_to_text(text);
178
log_error(0, _("au_to_text: failed"));
180
tok = au_to_return32(EPERM, 1);
182
log_error(0, _("au_to_return32: failed"));
184
if (au_close(aufd, 1, AUE_sudo) == -1)
185
log_error(0, _("unable to commit audit record"));