File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / bsm_audit.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:12:54 2014 UTC (10 years, 3 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_10p3_0, v1_8_10p3, HEAD
sudo v 1.8.10p3

    1: /*
    2:  * Copyright (c) 2009-2013 Todd C. Miller <Todd.Miller@courtesan.com>
    3:  * Copyright (c) 2009 Christian S.J. Peron
    4:  *
    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.
    8:  *
    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.
   16:  */
   17: 
   18: #include <config.h>
   19: 
   20: #include <sys/types.h>
   21: 
   22: #include <bsm/audit.h>
   23: #include <bsm/libbsm.h>
   24: #include <bsm/audit_uevents.h>
   25: 
   26: #include <stdio.h>
   27: #include <string.h>
   28: #include <stdarg.h>
   29: #include <pwd.h>
   30: #include <errno.h>
   31: #include <unistd.h>
   32: 
   33: #define DEFAULT_TEXT_DOMAIN	"sudoers"
   34: #include "gettext.h"		/* must be included before missing.h */
   35: 
   36: #include "missing.h"
   37: #include "fatal.h"
   38: #include "sudo_debug.h"
   39: #include "bsm_audit.h"
   40: 
   41: /*
   42:  * Solaris auditon() returns EINVAL if BSM audit not configured.
   43:  * OpenBSM returns ENOSYS for unimplemented options.
   44:  */
   45: #ifdef __sun
   46: # define AUDIT_NOT_CONFIGURED	EINVAL
   47: #else
   48: # define AUDIT_NOT_CONFIGURED	ENOSYS
   49: #endif
   50: 
   51: static int
   52: audit_sudo_selected(int sf)
   53: {
   54: 	auditinfo_addr_t ainfo_addr;
   55: 	struct au_mask *mask;
   56: 	auditinfo_t ainfo;
   57: 	int rc, sorf;
   58: 	debug_decl(audit_sudo_selected, SUDO_DEBUG_AUDIT)
   59: 
   60: 	if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) {
   61: 		if (errno == ENOSYS) {
   62: 			if (getaudit(&ainfo) < 0)
   63: 				fatal("getaudit");
   64: 			mask = &ainfo.ai_mask;
   65: 		} else
   66: 			fatal("getaudit");
   67:         } else
   68: 		mask = &ainfo_addr.ai_mask;
   69: 	sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE;
   70: 	rc = au_preselect(AUE_sudo, mask, sorf, AU_PRS_REREAD);
   71:         debug_return_int(rc);
   72: }
   73: 
   74: void
   75: bsm_audit_success(char **exec_args)
   76: {
   77: 	auditinfo_addr_t ainfo_addr;
   78: 	auditinfo_t ainfo;
   79: 	token_t *tok;
   80: 	au_id_t auid;
   81: 	long au_cond;
   82: 	int aufd;
   83: 	pid_t pid;
   84: 	debug_decl(bsm_audit_success, SUDO_DEBUG_AUDIT)
   85: 
   86: 	pid = getpid();
   87: 	/*
   88: 	 * If we are not auditing, don't cut an audit record; just return.
   89: 	 */
   90: 	if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
   91: 		if (errno == AUDIT_NOT_CONFIGURED)
   92: 			return;
   93: 		fatal(U_("Could not determine audit condition"));
   94: 	}
   95: 	if (au_cond == AUC_NOAUDIT)
   96: 		debug_return;
   97: 	/*
   98: 	 * Check to see if the preselection masks are interested in seeing
   99: 	 * this event.
  100: 	 */
  101: 	if (!audit_sudo_selected(0))
  102: 		debug_return;
  103: 	if (getauid(&auid) < 0)
  104: 		fatal("getauid");
  105: 	if ((aufd = au_open()) == -1)
  106: 		fatal("au_open");
  107: 	if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
  108: 		tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
  109: 		    getuid(), pid, pid, &ainfo_addr.ai_termid);
  110: 	} else if (errno == ENOSYS) {
  111: 		/*
  112: 		 * NB: We should probably watch out for ERANGE here.
  113: 		 */
  114: 		if (getaudit(&ainfo) < 0)
  115: 			fatal("getaudit");
  116: 		tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
  117: 		    getuid(), pid, pid, &ainfo.ai_termid);
  118: 	} else
  119: 		fatal("getaudit");
  120: 	if (tok == NULL)
  121: 		fatal("au_to_subject");
  122: 	au_write(aufd, tok);
  123: 	tok = au_to_exec_args(exec_args);
  124: 	if (tok == NULL)
  125: 		fatal("au_to_exec_args");
  126: 	au_write(aufd, tok);
  127: 	tok = au_to_return32(0, 0);
  128: 	if (tok == NULL)
  129: 		fatal("au_to_return32");
  130: 	au_write(aufd, tok);
  131: #ifdef __sun
  132: 	if (au_close(aufd, 1, AUE_sudo, 0) == -1)
  133: #else
  134: 	if (au_close(aufd, 1, AUE_sudo) == -1)
  135: #endif
  136: 		fatal(U_("unable to commit audit record"));
  137: 	debug_return;
  138: }
  139: 
  140: void
  141: bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap)
  142: {
  143: 	auditinfo_addr_t ainfo_addr;
  144: 	auditinfo_t ainfo;
  145: 	char text[256];
  146: 	token_t *tok;
  147: 	long au_cond;
  148: 	au_id_t auid;
  149: 	pid_t pid;
  150: 	int aufd;
  151: 	debug_decl(bsm_audit_success, SUDO_DEBUG_AUDIT)
  152: 
  153: 	pid = getpid();
  154: 	/*
  155: 	 * If we are not auditing, don't cut an audit record; just return.
  156: 	 */
  157: 	if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
  158: 		if (errno == AUDIT_NOT_CONFIGURED)
  159: 			debug_return;
  160: 		fatal(U_("Could not determine audit condition"));
  161: 	}
  162: 	if (au_cond == AUC_NOAUDIT)
  163: 		debug_return;
  164: 	if (!audit_sudo_selected(1))
  165: 		debug_return;
  166: 	if (getauid(&auid) < 0)
  167: 		fatal("getauid");
  168: 	if ((aufd = au_open()) == -1)
  169: 		fatal("au_open");
  170: 	if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) { 
  171: 		tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
  172: 		    getuid(), pid, pid, &ainfo_addr.ai_termid);
  173: 	} else if (errno == ENOSYS) {
  174: 		if (getaudit(&ainfo) < 0) 
  175: 			fatal("getaudit");
  176: 		tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
  177: 		    getuid(), pid, pid, &ainfo.ai_termid);
  178: 	} else
  179: 		fatal("getaudit");
  180: 	if (tok == NULL)
  181: 		fatal("au_to_subject");
  182: 	au_write(aufd, tok);
  183: 	tok = au_to_exec_args(exec_args);
  184: 	if (tok == NULL)
  185: 		fatal("au_to_exec_args");
  186: 	au_write(aufd, tok);
  187: 	(void) vsnprintf(text, sizeof(text), fmt, ap);
  188: 	tok = au_to_text(text);
  189: 	if (tok == NULL)
  190: 		fatal("au_to_text");
  191: 	au_write(aufd, tok);
  192: 	tok = au_to_return32(EPERM, 1);
  193: 	if (tok == NULL)
  194: 		fatal("au_to_return32");
  195: 	au_write(aufd, tok);
  196: #ifdef __sun
  197: 	if (au_close(aufd, 1, AUE_sudo, PAD_FAILURE) == -1)
  198: #else
  199: 	if (au_close(aufd, 1, AUE_sudo) == -1)
  200: #endif
  201: 		fatal(U_("unable to commit audit record"));
  202: 	debug_return;
  203: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>