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 #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 */ 54 static 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 */ 60 void 61 au_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, "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, "could not calculate audit mask"); 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, "setaudit failed"); 92 93 if ((aufd = au_open()) == -1) 94 errx(1, "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, "audit error: au_to_subject32() failed"); 99 au_write(aufd, tok); 100 101 if ((tok = au_to_return32(0, 0)) == NULL) 102 errx(1, "audit error: au_to_return32() failed"); 103 au_write(aufd, tok); 104 105 if (au_close(aufd, 1, AUE_login) == -1) 106 errx(1, "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 */ 113 void 114 au_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, "could not determine audit condition"); 128 } 129 if (au_cond == AUC_NOAUDIT) 130 return; 131 132 if ((aufd = au_open()) == -1) 133 errx(1, "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, "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, "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, "audit error: au_to_text() failed"); 156 au_write(aufd, tok); 157 158 if ((tok = au_to_return32(1, errno)) == NULL) 159 errx(1, "audit error: au_to_return32() failed"); 160 au_write(aufd, tok); 161 162 if (au_close(aufd, 1, AUE_login) == -1) 163 errx(1, "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 */ 170 void 171 audit_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(au_cond)) < 0) { 182 if (errno == ENOSYS) 183 return; 184 errx(1, "could not determine audit condition"); 185 } 186 if (au_cond == AUC_NOAUDIT) 187 return; 188 189 if ((aufd = au_open()) == -1) 190 errx(1, "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, "audit error: au_to_subject32() failed"); 196 au_write(aufd, tok); 197 198 if ((tok = au_to_return32(0, 0)) == NULL) 199 errx(1, "audit error: au_to_return32() failed"); 200 au_write(aufd, tok); 201 202 if (au_close(aufd, 1, AUE_logout) == -1) 203 errx(1, "audit record was not committed."); 204 } 205