Return to bsm_audit.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers |
1.1 ! misho 1: /* ! 2: * Copyright (c) 2009-2011 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: #include "bsm_audit.h" ! 34: ! 35: /* ! 36: * Solaris auditon() returns EINVAL if BSM audit not configured. ! 37: * OpenBSM returns ENOSYS for unimplemented options. ! 38: */ ! 39: #ifdef __sun ! 40: # define AUDIT_NOT_CONFIGURED EINVAL ! 41: #else ! 42: # define AUDIT_NOT_CONFIGURED ENOSYS ! 43: #endif ! 44: ! 45: void log_error(int flags, const char *fmt, ...) __attribute__((__noreturn__)); ! 46: ! 47: static int ! 48: audit_sudo_selected(int sf) ! 49: { ! 50: auditinfo_addr_t ainfo_addr; ! 51: struct au_mask *mask; ! 52: auditinfo_t ainfo; ! 53: int rc, sorf; ! 54: ! 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; ! 60: } else ! 61: log_error(0, _("getaudit: failed")); ! 62: } else ! 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); ! 66: return rc; ! 67: } ! 68: ! 69: void ! 70: bsm_audit_success(char **exec_args) ! 71: { ! 72: auditinfo_addr_t ainfo_addr; ! 73: auditinfo_t ainfo; ! 74: token_t *tok; ! 75: au_id_t auid; ! 76: long au_cond; ! 77: int aufd; ! 78: pid_t pid; ! 79: ! 80: pid = getpid(); ! 81: /* ! 82: * If we are not auditing, don't cut an audit record; just return. ! 83: */ ! 84: if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) { ! 85: if (errno == AUDIT_NOT_CONFIGURED) ! 86: return; ! 87: log_error(0, _("Could not determine audit condition")); ! 88: } ! 89: if (au_cond == AUC_NOAUDIT) ! 90: return; ! 91: /* ! 92: * Check to see if the preselection masks are interested in seeing ! 93: * this event. ! 94: */ ! 95: if (!audit_sudo_selected(0)) ! 96: return; ! 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) { ! 105: /* ! 106: * NB: We should probably watch out for ERANGE here. ! 107: */ ! 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); ! 112: } else ! 113: log_error(0, _("getaudit: failed")); ! 114: if (tok == NULL) ! 115: log_error(0, _("au_to_subject: failed")); ! 116: au_write(aufd, tok); ! 117: tok = au_to_exec_args(exec_args); ! 118: if (tok == NULL) ! 119: log_error(0, _("au_to_exec_args: failed")); ! 120: au_write(aufd, tok); ! 121: tok = au_to_return32(0, 0); ! 122: if (tok == NULL) ! 123: log_error(0, _("au_to_return32: failed")); ! 124: au_write(aufd, tok); ! 125: if (au_close(aufd, 1, AUE_sudo) == -1) ! 126: log_error(0, _("unable to commit audit record")); ! 127: } ! 128: ! 129: void ! 130: bsm_audit_failure(char **exec_args, char const *const fmt, va_list ap) ! 131: { ! 132: auditinfo_addr_t ainfo_addr; ! 133: auditinfo_t ainfo; ! 134: char text[256]; ! 135: token_t *tok; ! 136: long au_cond; ! 137: au_id_t auid; ! 138: pid_t pid; ! 139: int aufd; ! 140: ! 141: pid = getpid(); ! 142: /* ! 143: * If we are not auditing, don't cut an audit record; just return. ! 144: */ ! 145: if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) { ! 146: if (errno == AUDIT_NOT_CONFIGURED) ! 147: return; ! 148: log_error(0, _("Could not determine audit condition")); ! 149: } ! 150: if (au_cond == AUC_NOAUDIT) ! 151: return; ! 152: if (!audit_sudo_selected(1)) ! 153: return; ! 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); ! 166: } else ! 167: log_error(0, _("getaudit: failed")); ! 168: if (tok == NULL) ! 169: log_error(0, _("au_to_subject: failed")); ! 170: au_write(aufd, tok); ! 171: tok = au_to_exec_args(exec_args); ! 172: if (tok == NULL) ! 173: log_error(0, _("au_to_exec_args: failed")); ! 174: au_write(aufd, tok); ! 175: (void) vsnprintf(text, sizeof(text), fmt, ap); ! 176: tok = au_to_text(text); ! 177: if (tok == NULL) ! 178: log_error(0, _("au_to_text: failed")); ! 179: au_write(aufd, tok); ! 180: tok = au_to_return32(EPERM, 1); ! 181: if (tok == NULL) ! 182: log_error(0, _("au_to_return32: failed")); ! 183: au_write(aufd, tok); ! 184: if (au_close(aufd, 1, AUE_sudo) == -1) ! 185: log_error(0, _("unable to commit audit record")); ! 186: }