2 * Copyright (c) 2005-2016 Apple Inc. All rights reserved.
4 * @APPLE_BSD_LICENSE_HEADER_START@
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * @APPLE_BSD_LICENSE_HEADER_END@
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD: src/usr.bin/login/login_audit.c,v 1.2 2007/05/07 11:01:36 dwmalone Exp $");
38 #include <sys/types.h>
40 #include <bsm/libbsm.h>
41 #include <bsm/audit_uevents.h>
42 #include <bsm/audit_session.h>
60 * The following tokens are included in the audit record for a successful
61 * login: header, subject, return.
64 au_login_success(int fflag
)
68 auditinfo_addr_t auinfo
;
69 uid_t uid
= pwd
->pw_uid
;
70 gid_t gid
= pwd
->pw_gid
;
74 /* Determine whether auditing is enabled. */
75 if (auditon(A_GETCOND
, &au_cond
, sizeof(long)) < 0) {
78 errx(1, "login: Could not determine audit condition");
81 /* Initialize with the current audit info. */
82 if (getaudit_addr(&auinfo
, sizeof(auinfo
)) < 0) {
83 err(1, "getaudit_addr");
85 auinfo
.ai_auid
= pwd
->pw_uid
;
86 memcpy(&auinfo
.ai_termid
, &tid
, sizeof(auinfo
.ai_termid
));
88 /* Do the SessionCreate() equivalent. */
90 auinfo
.ai_asid
= AU_ASSIGN_ASID
;
91 auinfo
.ai_flags
|= AU_SESSION_FLAG_HAS_TTY
;
92 auinfo
.ai_flags
|= AU_SESSION_FLAG_HAS_AUTHENTICATED
;
95 if (au_cond
!= AUC_NOAUDIT
) {
96 /* Compute and set the user's preselection mask. */
97 if (au_user_mask(pwd
->pw_name
, &auinfo
.ai_mask
) < 0) {
98 errx(1, "login: Could not set audit mask\n");
102 if (setaudit_addr(&auinfo
, sizeof(auinfo
)) < 0)
103 err(1, "login: setaudit_addr failed");
105 char *session
= NULL
;
106 asprintf(&session
, "%x", auinfo
.ai_asid
);
107 if (NULL
== session
) {
108 errx(1, "asprintf failed");
110 setenv("SECURITYSESSIONID", session
, 1);
113 /* If we are not auditing, don't cut an audit record; just return. */
114 if (au_cond
== AUC_NOAUDIT
)
117 if ((aufd
= au_open()) == -1)
118 errx(1,"login: Audit Error: au_open() failed");
120 if ((tok
= au_to_subject32_ex(uid
, geteuid(), getegid(), uid
, gid
, pid
,
122 errx(1, "login: Audit Error: au_to_subject32() failed");
125 if ((tok
= au_to_return32(0, 0)) == NULL
)
126 errx(1, "login: Audit Error: au_to_return32() failed");
129 if (au_close(aufd
, 1, AUE_login
) == -1)
130 errx(1, "login: Audit Record was not committed.");
134 * The following tokens are included in the audit record for failed
135 * login attempts: header, subject, text, return.
138 au_login_fail(const char *errmsg
, int na
)
145 pid_t pid
= getpid();
147 /* If we are not auditing, don't cut an audit record; just return. */
148 if (auditon(A_GETCOND
, &au_cond
, sizeof(long)) < 0) {
151 errx(1, "login: Could not determine audit condition");
153 if (au_cond
== AUC_NOAUDIT
)
156 if ((aufd
= au_open()) == -1)
157 errx(1, "login: Audit Error: au_open() failed");
161 * Non attributable event. Assuming that login is not called
162 * within a user's session => auid,asid == -1.
164 if ((tok
= au_to_subject32_ex(-1, geteuid(), getegid(), -1, -1,
165 pid
, -1, &tid
)) == NULL
)
166 errx(1, "login: Audit Error: au_to_subject32() failed");
168 /* We know the subject -- so use its value instead. */
171 if ((tok
= au_to_subject32_ex(uid
, geteuid(), getegid(), uid
,
172 gid
, pid
, pid
, &tid
)) == NULL
)
173 errx(1, "login: Audit Error: au_to_subject32() failed");
177 /* Include the error message. */
178 if ((tok
= au_to_text(errmsg
)) == NULL
)
179 errx(1, "login: Audit Error: au_to_text() failed");
182 if ((tok
= au_to_return32(1, errno
)) == NULL
)
183 errx(1, "login: Audit Error: au_to_return32() failed");
186 if (au_close(aufd
, 1, AUE_login
) == -1)
187 errx(1, "login: Audit Error: au_close() was not committed");
191 * The following tokens are included in the audit record for a logout:
192 * header, subject, return.
199 uid_t uid
= pwd
->pw_uid
;
200 gid_t gid
= pwd
->pw_gid
;
201 pid_t pid
= getpid();
204 /* If we are not auditing, don't cut an audit record; just return. */
205 if (auditon(A_GETCOND
, &au_cond
, sizeof(long)) < 0) {
208 errx(1, "login: Could not determine audit condition");
210 if (au_cond
== AUC_NOAUDIT
)
213 if ((aufd
= au_open()) == -1)
214 errx(1, "login: Audit Error: au_open() failed");
216 /* The subject that is created (euid, egid of the current process). */
217 if ((tok
= au_to_subject32_ex(uid
, geteuid(), getegid(), uid
, gid
, pid
,
219 errx(1, "login: Audit Error: au_to_subject32() failed");
222 if ((tok
= au_to_return32(0, 0)) == NULL
)
223 errx(1, "login: Audit Error: au_to_return32() failed");
226 if (au_close(aufd
, 1, AUE_logout
) == -1)
227 errx(1, "login: Audit Record was not committed.");
230 #endif /* USE_BSM_AUDIT */