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