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$"); 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#include <strings.h> 47#include <unistd.h> 48 49#include "login.h" 50 51/* 52 * Audit data 53 */ 54static au_tid_t tid; 55 56/* 57 * The following tokens are included in the audit record for a successful 58 * login: header, subject, return. 59 */ 60void 61au_login_success(void) 62{ 63 token_t *tok; 64 int aufd; 65 au_mask_t aumask; 66 auditinfo_t auinfo; 67 uid_t uid = pwd->pw_uid; 68 gid_t gid = pwd->pw_gid; 69 pid_t pid = getpid(); 70 int au_cond; 71 72 /* If we are not auditing, don't cut an audit record; just return. */ 73 if (auditon(A_GETCOND, &au_cond, sizeof(au_cond)) < 0) { 74 if (errno == ENOSYS) 75 return; 76 errx(1, "login: Could not determine audit condition"); 77 } 78 if (au_cond == AUC_NOAUDIT) 79 return; 80 81 /* Compute and set the user's preselection mask. */ 82 if (au_user_mask(pwd->pw_name, &aumask) == -1) 83 errx(1, "login: Could not set audit mask\n"); 84 85 /* Set the audit info for the user. */ 86 auinfo.ai_auid = uid; 87 auinfo.ai_asid = pid; 88 bcopy(&tid, &auinfo.ai_termid, sizeof(auinfo.ai_termid)); 89 bcopy(&aumask, &auinfo.ai_mask, sizeof(auinfo.ai_mask)); 90 if (setaudit(&auinfo) != 0) 91 err(1, "login: setaudit failed"); 92 93 if ((aufd = au_open()) == -1) 94 errx(1,"login: Audit Error: au_open() failed"); 95 96 if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid, gid, pid, 97 pid, &tid)) == NULL) 98 errx(1, "login: Audit Error: au_to_subject32() failed"); 99 au_write(aufd, tok); 100 101 if ((tok = au_to_return32(0, 0)) == NULL) 102 errx(1, "login: Audit Error: au_to_return32() failed"); 103 au_write(aufd, tok); 104 105 if (au_close(aufd, 1, AUE_login) == -1) 106 errx(1, "login: Audit Record was not committed."); 107} 108 109/* 110 * The following tokens are included in the audit record for failed 111 * login attempts: header, subject, text, return. 112 */ 113void 114au_login_fail(const char *errmsg, int na) 115{ 116 token_t *tok; 117 int aufd; 118 int au_cond; 119 uid_t uid; 120 gid_t gid; 121 pid_t pid = getpid(); 122 123 /* If we are not auditing, don't cut an audit record; just return. */ 124 if (auditon(A_GETCOND, &au_cond, sizeof(au_cond)) < 0) { 125 if (errno == ENOSYS) 126 return; 127 errx(1, "login: Could not determine audit condition"); 128 } 129 if (au_cond == AUC_NOAUDIT) 130 return; 131 132 if ((aufd = au_open()) == -1) 133 errx(1, "login: Audit Error: au_open() failed"); 134 135 if (na) { 136 /* 137 * Non attributable event. Assuming that login is not called 138 * within a user's session => auid,asid == -1. 139 */ 140 if ((tok = au_to_subject32(-1, geteuid(), getegid(), -1, -1, 141 pid, -1, &tid)) == NULL) 142 errx(1, "login: Audit Error: au_to_subject32() failed"); 143 } else { 144 /* We know the subject -- so use its value instead. */ 145 uid = pwd->pw_uid; 146 gid = pwd->pw_gid; 147 if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid, 148 gid, pid, pid, &tid)) == NULL) 149 errx(1, "login: Audit Error: au_to_subject32() failed"); 150 } 151 au_write(aufd, tok); 152 153 /* Include the error message. */ 154 if ((tok = au_to_text(errmsg)) == NULL) 155 errx(1, "login: Audit Error: au_to_text() failed"); 156 au_write(aufd, tok); 157 158 if ((tok = au_to_return32(1, errno)) == NULL) 159 errx(1, "login: Audit Error: au_to_return32() failed"); 160 au_write(aufd, tok); 161 162 if (au_close(aufd, 1, AUE_login) == -1) 163 errx(1, "login: Audit Error: au_close() was not committed"); 164} 165 166/* 167 * The following tokens are included in the audit record for a logout: 168 * header, subject, return. 169 */ 170void 171audit_logout(void) 172{ 173 token_t *tok; 174 int aufd; 175 uid_t uid = pwd->pw_uid; 176 gid_t gid = pwd->pw_gid; 177 pid_t pid = getpid(); 178 int 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(int)) < 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