/*
 * Copyright (c) 2009 Christian S.J. Peron
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <config.h>

#include <sys/types.h>

#include <bsm/audit.h>
#include <bsm/libbsm.h>
#include <bsm/audit_uevents.h>

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <pwd.h>
#include <errno.h>
#include <unistd.h>

#include "bsm_audit.h"

void log_error(int flags, const char *fmt, ...) __attribute__((__noreturn__));

static int
audit_sudo_selected(int sf)
{
	auditinfo_addr_t ainfo_addr;
	struct au_mask *mask;
	auditinfo_t ainfo;
	int rc, sorf;

	if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) {
		if (errno == ENOSYS) {
			if (getaudit(&ainfo) < 0)
				log_error(0, "getaudit: failed");
			mask = &ainfo.ai_mask;
		} else
			log_error(0, "getaudit: failed");
        } else
		mask = &ainfo_addr.ai_mask;
	sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE;
	rc = au_preselect(AUE_sudo, mask, sorf, AU_PRS_REREAD);
        return (rc);
}

void
bsm_audit_success(char **exec_args)
{
	auditinfo_addr_t ainfo_addr;
	auditinfo_t ainfo;
	token_t *tok;
	au_id_t auid;
	long au_cond;
	int aufd;
	pid_t pid;

	pid = getpid();
	/*
	 * If we are not auditing, don't cut an audit record; just return.
	 */
	if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
		if (errno == ENOSYS)
			return;
		log_error(0, "Could not determine audit condition");
	}
	if (au_cond == AUC_NOAUDIT)
		return;
	/*
	 * Check to see if the preselection masks are interested in seeing
	 * this event.
	 */
	if (!audit_sudo_selected(0))
		return;
	if (getauid(&auid) < 0)
		log_error(0, "getauid failed");
	if ((aufd = au_open()) == -1)
		log_error(0, "au_open: failed");
	if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
		tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
		    getuid(), pid, pid, &ainfo_addr.ai_termid);
	} else if (errno == ENOSYS) {
		/*
		 * NB: We should probably watch out for ERANGE here.
		 */
		if (getaudit(&ainfo) < 0)
			log_error(0, "getaudit: failed");
		tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
		    getuid(), pid, pid, &ainfo.ai_termid);
	} else
		log_error(0, "getaudit: failed");
	if (tok == NULL)
		log_error(0, "au_to_subject: failed");
	au_write(aufd, tok);
	tok = au_to_exec_args(exec_args);
	if (tok == NULL)
		log_error(0, "au_to_exec_args: failed");
	au_write(aufd, tok);
	tok = au_to_return32(0, 0);
	if (tok == NULL)
		log_error(0, "au_to_return32: failed");
	au_write(aufd, tok);
	if (au_close(aufd, 1, AUE_sudo) == -1)
		log_error(0, "unable to commit audit record");
}

void
bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap)
{
	auditinfo_addr_t ainfo_addr;
	auditinfo_t ainfo;
	char text[256];
	token_t *tok;
	long au_cond;
	au_id_t auid;
	pid_t pid;
	int aufd;

	pid = getpid();
	/*
	 * If we are not auditing, don't cut an audit record; just return.
	 */
	if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
		if (errno == ENOSYS)
			return;
		log_error(0, "Could not determine audit condition");
	}
	if (au_cond == AUC_NOAUDIT)
		return;
	if (!audit_sudo_selected(1))
		return;
	if (getauid(&auid) < 0)
		log_error(0, "getauid: failed");
	if ((aufd = au_open()) == -1)
		log_error(0, "au_open: failed");
	if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) { 
		tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
		    getuid(), pid, pid, &ainfo_addr.ai_termid);
	} else if (errno == ENOSYS) {
		if (getaudit(&ainfo) < 0) 
			log_error(0, "getaudit: failed");
		tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
		    getuid(), pid, pid, &ainfo.ai_termid);
	} else
		log_error(0, "getaudit: failed");
	if (tok == NULL)
		log_error(0, "au_to_subject: failed");
	au_write(aufd, tok);
	tok = au_to_exec_args(exec_args);
	if (tok == NULL)
		log_error(0, "au_to_exec_args: failed");
	au_write(aufd, tok);
	(void) vsnprintf(text, sizeof(text), fmt, ap);
	tok = au_to_text(text);
	if (tok == NULL)
		log_error(0, "au_to_text: failed");
	au_write(aufd, tok);
	tok = au_to_return32(EPERM, 1);
	if (tok == NULL)
		log_error(0, "au_to_return32: failed");
	au_write(aufd, tok);
	if (au_close(aufd, 1, AUE_sudo) == -1)
		log_error(0, "unable to commit audit record");
}
