login_audit.c revision 155312
1/* 2 * Copyright (c) 2005 Apple Computer, Inc. 3 * All rights reserved. 4 * 5 * @APPLE_BSD_LICENSE_HEADER_START@ 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * @APPLE_BSD_LICENSE_HEADER_END@ 32 */ 33 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: head/usr.bin/login/login_audit.c 155312 2006-02-04 20:20:02Z wsalamon $"); 36 37#include <sys/types.h> 38 39#include <bsm/libbsm.h> 40#include <bsm/audit_uevents.h> 41 42#include <err.h> 43#include <errno.h> 44#include <pwd.h> 45#include <stdio.h> 46 47#include "login.h" 48 49/* 50 * Audit data 51 */ 52static au_tid_t tid; 53 54/* 55 * The following tokens are included in the audit record for a successful 56 * login: header, subject, return. 57 */ 58void 59au_login_success(void) 60{ 61 token_t *tok; 62 int aufd; 63 au_mask_t aumask; 64 auditinfo_t auinfo; 65 uid_t uid = pwd->pw_uid; 66 gid_t gid = pwd->pw_gid; 67 pid_t pid = getpid(); 68 long au_cond; 69 70 /* If we are not auditing, don't cut an audit record; just return. */ 71 if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) { 72 if (errno == ENOSYS) 73 return; 74 errx(1, "login: Could not determine audit condition"); 75 } 76 if (au_cond == AUC_NOAUDIT) 77 return; 78 79 /* Compute and set the user's preselection mask. */ 80 if (au_user_mask(pwd->pw_name, &aumask) == -1) 81 errx(1, "login: Could not set audit mask\n"); 82 83 /* Set the audit info for the user. */ 84 auinfo.ai_auid = uid; 85 auinfo.ai_asid = pid; 86 bcopy(&tid, &auinfo.ai_termid, sizeof(auinfo.ai_termid)); 87 bcopy(&aumask, &auinfo.ai_mask, sizeof(auinfo.ai_mask)); 88 if (setaudit(&auinfo) != 0) 89 err(1, "login: setaudit failed"); 90 91 if ((aufd = au_open()) == -1) 92 errx(1,"login: Audit Error: au_open() failed"); 93 94 if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid, gid, pid, 95 pid, &tid)) == NULL) 96 errx(1, "login: Audit Error: au_to_subject32() failed"); 97 au_write(aufd, tok); 98 99 if ((tok = au_to_return32(0, 0)) == NULL) 100 errx(1, "login: Audit Error: au_to_return32() failed"); 101 au_write(aufd, tok); 102 103 if (au_close(aufd, 1, AUE_login) == -1) 104 errx(1, "login: Audit Record was not committed."); 105} 106 107/* 108 * The following tokens are included in the audit record for failed 109 * login attempts: header, subject, text, return. 110 */ 111void 112au_login_fail(char *errmsg, int na) 113{ 114 token_t *tok; 115 int aufd; 116 long au_cond; 117 uid_t uid; 118 gid_t gid; 119 pid_t pid = getpid(); 120 121 /* If we are not auditing, don't cut an audit record; just return. */ 122 if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) { 123 if (errno == ENOSYS) 124 return; 125 errx(1, "login: Could not determine audit condition"); 126 } 127 if (au_cond == AUC_NOAUDIT) 128 return; 129 130 if ((aufd = au_open()) == -1) 131 errx(1, "login: Audit Error: au_open() failed"); 132 133 if (na) { 134 /* 135 * Non attributable event. Assuming that login is not called 136 * within a user's session => auid,asid == -1. 137 */ 138 if ((tok = au_to_subject32(-1, geteuid(), getegid(), -1, -1, 139 pid, -1, &tid)) == NULL) 140 errx(1, "login: Audit Error: au_to_subject32() failed"); 141 } else { 142 /* We know the subject -- so use its value instead. */ 143 uid = pwd->pw_uid; 144 gid = pwd->pw_gid; 145 if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid, 146 gid, pid, pid, &tid)) == NULL) 147 errx(1, "login: Audit Error: au_to_subject32() failed"); 148 } 149 au_write(aufd, tok); 150 151 /* Include the error message. */ 152 if ((tok = au_to_text(errmsg)) == NULL) 153 errx(1, "login: Audit Error: au_to_text() failed"); 154 au_write(aufd, tok); 155 156 if ((tok = au_to_return32(1, errno)) == NULL) 157 errx(1, "login: Audit Error: au_to_return32() failed"); 158 au_write(aufd, tok); 159 160 if (au_close(aufd, 1, AUE_login) == -1) 161 errx(1, "login: Audit Error: au_close() was not committed"); 162} 163 164/* 165 * The following tokens are included in the audit record for a logout: 166 * header, subject, return. 167 */ 168void 169audit_logout(void) 170{ 171 token_t *tok; 172 int aufd; 173 au_mask_t aumask; 174 auditinfo_t auinfo; 175 uid_t uid = pwd->pw_uid; 176 gid_t gid = pwd->pw_gid; 177 pid_t pid = getpid(); 178 long au_cond; 179 180 /* If we are not auditing, don't cut an audit record; just return. */ 181 if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) { 182 if (errno == ENOSYS) 183 return; 184 errx(1, "login: Could not determine audit condition"); 185 } 186 if (au_cond == AUC_NOAUDIT) 187 return; 188 189 if ((aufd = au_open()) == -1) 190 errx(1, "login: Audit Error: au_open() failed"); 191 192 /* The subject that is created (euid, egid of the current process). */ 193 if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid, gid, pid, 194 pid, &tid)) == NULL) 195 errx(1, "login: Audit Error: au_to_subject32() failed"); 196 au_write(aufd, tok); 197 198 if ((tok = au_to_return32(0, 0)) == NULL) 199 errx(1, "login: Audit Error: au_to_return32() failed"); 200 au_write(aufd, tok); 201 202 if (au_close(aufd, 1, AUE_logout) == -1) 203 errx(1, "login: Audit Record was not committed."); 204} 205