summaryrefslogtreecommitdiffstats
path: root/contrib/openbsm/libbsm/bsm_wrappers.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/openbsm/libbsm/bsm_wrappers.c')
-rw-r--r--contrib/openbsm/libbsm/bsm_wrappers.c127
1 files changed, 118 insertions, 9 deletions
diff --git a/contrib/openbsm/libbsm/bsm_wrappers.c b/contrib/openbsm/libbsm/bsm_wrappers.c
index 72020ce..98f286c 100644
--- a/contrib/openbsm/libbsm/bsm_wrappers.c
+++ b/contrib/openbsm/libbsm/bsm_wrappers.c
@@ -26,7 +26,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#18 $
+ * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#23 $
*/
#ifdef __APPLE__
@@ -46,6 +46,7 @@
#include <unistd.h>
#include <syslog.h>
+#include <stdarg.h>
#include <string.h>
#include <errno.h>
@@ -53,6 +54,115 @@
int audit_set_terminal_port(dev_t *p);
int audit_set_terminal_host(uint32_t *m);
+/*
+ * General purpose audit submission mechanism for userspace.
+ */
+int
+audit_submit(short au_event, au_id_t auid, char status,
+ int reterr, const char *fmt, ...)
+{
+ char text[MAX_AUDITSTRING_LEN];
+ token_t *token;
+ long acond;
+ va_list ap;
+ pid_t pid;
+ int error, afd;
+ struct auditinfo ai;
+
+ if (auditon(A_GETCOND, &acond, sizeof(acond)) < 0) {
+ /*
+ * If auditon(2) returns ENOSYS, then audit has not been
+ * compiled into the kernel, so just return.
+ */
+ if (errno == ENOSYS)
+ return (0);
+ error = errno;
+ syslog(LOG_AUTH | LOG_ERR, "audit: auditon failed: %s",
+ strerror(errno));
+ errno = error;
+ return (-1);
+ }
+ if (acond == AUC_NOAUDIT)
+ return (0);
+ afd = au_open();
+ if (afd < 0) {
+ error = errno;
+ syslog(LOG_AUTH | LOG_ERR, "audit: au_open failed: %s",
+ strerror(errno));
+ errno = error;
+ return (-1);
+ }
+ if (getaudit(&ai) < 0) {
+ error = errno;
+ syslog(LOG_AUTH | LOG_ERR, "audit: getaudit failed: %s",
+ strerror(errno));
+ errno = error;
+ return (-1);
+ }
+ pid = getpid();
+ token = au_to_subject32(auid, geteuid(), getegid(),
+ getuid(), getgid(), pid, pid, &ai.ai_termid);
+ if (token == NULL) {
+ syslog(LOG_AUTH | LOG_ERR,
+ "audit: unable to build subject token");
+ (void) au_close(afd, AU_TO_NO_WRITE, au_event);
+ errno = EPERM;
+ return (-1);
+ }
+ if (au_write(afd, token) < 0) {
+ error = errno;
+ syslog(LOG_AUTH | LOG_ERR,
+ "audit: au_write failed: %s", strerror(errno));
+ (void) au_close(afd, AU_TO_NO_WRITE, au_event);
+ errno = error;
+ return (-1);
+ }
+ if (fmt != NULL) {
+ va_start(ap, fmt);
+ (void) vsnprintf(text, MAX_AUDITSTRING_LEN, fmt, ap);
+ va_end(ap);
+ token = au_to_text(text);
+ if (token == NULL) {
+ syslog(LOG_AUTH | LOG_ERR,
+ "audit: failed to generate text token");
+ (void) au_close(afd, AU_TO_NO_WRITE, au_event);
+ errno = EPERM;
+ return (-1);
+ }
+ if (au_write(afd, token) < 0) {
+ error = errno;
+ syslog(LOG_AUTH | LOG_ERR,
+ "audit: au_write failed: %s", strerror(errno));
+ (void) au_close(afd, AU_TO_NO_WRITE, au_event);
+ errno = error;
+ return (-1);
+ }
+ }
+ token = au_to_return32(status, reterr);
+ if (token == NULL) {
+ syslog(LOG_AUTH | LOG_ERR,
+ "audit: enable to build return token");
+ (void) au_close(afd, AU_TO_NO_WRITE, au_event);
+ errno = EPERM;
+ return (-1);
+ }
+ if (au_write(afd, token) < 0) {
+ error = errno;
+ syslog(LOG_AUTH | LOG_ERR,
+ "audit: au_write failed: %s", strerror(errno));
+ (void) au_close(afd, AU_TO_NO_WRITE, au_event);
+ errno = error;
+ return (-1);
+ }
+ if (au_close(afd, AU_TO_WRITE, au_event) < 0) {
+ error = errno;
+ syslog(LOG_AUTH | LOG_ERR, "audit: record not committed");
+ errno = error;
+ return (-1);
+ }
+ return (0);
+}
+
int
audit_set_terminal_port(dev_t *p)
{
@@ -130,7 +240,7 @@ audit_set_terminal_id(au_tid_t *tid)
* tok = au_to_random_token_2(...);
* au_write(aufd, tok);
* ...
- * au_close(aufd, 1, AUE_your_event_type);
+ * au_close(aufd, AU_TO_WRITE, AUE_your_event_type);
*
* Assumes, like all wrapper calls, that the caller has previously checked
* that auditing is enabled via the audit_get_state() call.
@@ -156,7 +266,7 @@ audit_write(short event_code, token_t *subject, token_t *misctok, char retval,
if (subject && au_write(aufd, subject) == -1) {
au_free_token(subject);
au_free_token(misctok);
- (void)au_close(aufd, 0, event_code);
+ (void)au_close(aufd, AU_TO_WRITE, event_code);
syslog(LOG_ERR, "%s: write of subject failed", func);
return (kAUWriteSubjectTokErr);
}
@@ -164,31 +274,30 @@ audit_write(short event_code, token_t *subject, token_t *misctok, char retval,
/* Save the event-specific token. */
if (misctok && au_write(aufd, misctok) == -1) {
au_free_token(misctok);
- (void)au_close(aufd, 0, event_code);
+ (void)au_close(aufd, AU_TO_NO_WRITE, event_code);
syslog(LOG_ERR, "%s: write of caller token failed", func);
return (kAUWriteCallerTokErr);
}
/* Tokenize and save the return value. */
if ((rettok = au_to_return32(retval, errcode)) == NULL) {
- (void)au_close(aufd, 0, event_code);
+ (void)au_close(aufd, AU_TO_NO_WRITE, event_code);
syslog(LOG_ERR, "%s: au_to_return32() failed", func);
return (kAUMakeReturnTokErr);
}
if (au_write(aufd, rettok) == -1) {
au_free_token(rettok);
- (void)au_close(aufd, 0, event_code);
+ (void)au_close(aufd, AU_TO_NO_WRITE, event_code);
syslog(LOG_ERR, "%s: write of return code failed", func);
return (kAUWriteReturnTokErr);
}
/*
- * au_close()'s second argument is "keep": if keep == 0, the record is
- * discarded. We assume the caller wouldn't have bothered with this
+ * We assume the caller wouldn't have bothered with this
* function if it hadn't already decided to keep the record.
*/
- if (au_close(aufd, 1, event_code) < 0) {
+ if (au_close(aufd, AU_TO_WRITE, event_code) < 0) {
syslog(LOG_ERR, "%s: au_close() failed", func);
return (kAUCloseErr);
}
OpenPOWER on IntegriCloud