2 * Copyright (c) 2005 Apple Computer, Inc.
5 * @APPLE_BSD_LICENSE_HEADER_START@
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
31 * @APPLE_BSD_LICENSE_HEADER_END@
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD: src/usr.bin/login/login_audit.c,v 1.2 2007/05/07 11:01:36 dwmalone Exp $");
39 #include <sys/types.h>
41 #include <bsm/libbsm.h>
42 #include <bsm/audit_uevents.h>
43 #include <bsm/audit_session.h>
61 * The following tokens are included in the audit record for a successful
62 * login: header, subject, return.
65 au_login_success(int fflag
)
69 auditinfo_addr_t auinfo
;
70 uid_t uid
= pwd
->pw_uid
;
71 gid_t gid
= pwd
->pw_gid
;
75 /* Determine whether auditing is enabled. */
76 if (auditon(A_GETCOND
, &au_cond
, sizeof(long)) < 0) {
79 errx(1, "login: Could not determine audit condition");
82 /* Initialize with the current audit info. */
83 if (getaudit_addr(&auinfo
, sizeof(auinfo
)) < 0) {
84 err(1, "getaudit_addr");
86 auinfo
.ai_auid
= pwd
->pw_uid
;
87 memcpy(&auinfo
.ai_termid
, &tid
, sizeof(auinfo
.ai_termid
));
89 /* Do the SessionCreate() equivalent. */
91 auinfo
.ai_asid
= AU_ASSIGN_ASID
;
92 auinfo
.ai_flags
|= AU_SESSION_FLAG_HAS_TTY
;
93 auinfo
.ai_flags
|= AU_SESSION_FLAG_HAS_AUTHENTICATED
;
96 if (au_cond
!= AUC_NOAUDIT
) {
97 /* Compute and set the user's preselection mask. */
98 if (au_user_mask(pwd
->pw_name
, &auinfo
.ai_mask
) < 0) {
99 errx(1, "login: Could not set audit mask\n");
103 if (setaudit_addr(&auinfo
, sizeof(auinfo
)) < 0)
104 err(1, "login: setaudit_addr failed");
106 char *session
= NULL
;
107 asprintf(&session
, "%x", auinfo
.ai_asid
);
108 if (NULL
== session
) {
109 errx(1, "asprintf failed");
111 setenv("SECURITYSESSIONID", session
, 1);
114 /* If we are not auditing, don't cut an audit record; just return. */
115 if (au_cond
== AUC_NOAUDIT
)
118 if ((aufd
= au_open()) == -1)
119 errx(1,"login: Audit Error: au_open() failed");
121 if ((tok
= au_to_subject32_ex(uid
, geteuid(), getegid(), uid
, gid
, pid
,
123 errx(1, "login: Audit Error: au_to_subject32() failed");
126 if ((tok
= au_to_return32(0, 0)) == NULL
)
127 errx(1, "login: Audit Error: au_to_return32() failed");
130 if (au_close(aufd
, 1, AUE_login
) == -1)
131 errx(1, "login: Audit Record was not committed.");
135 * The following tokens are included in the audit record for failed
136 * login attempts: header, subject, text, return.
139 au_login_fail(const char *errmsg
, int na
)
146 pid_t pid
= getpid();
148 /* If we are not auditing, don't cut an audit record; just return. */
149 if (auditon(A_GETCOND
, &au_cond
, sizeof(long)) < 0) {
152 errx(1, "login: Could not determine audit condition");
154 if (au_cond
== AUC_NOAUDIT
)
157 if ((aufd
= au_open()) == -1)
158 errx(1, "login: Audit Error: au_open() failed");
162 * Non attributable event. Assuming that login is not called
163 * within a user's session => auid,asid == -1.
165 if ((tok
= au_to_subject32_ex(-1, geteuid(), getegid(), -1, -1,
166 pid
, -1, &tid
)) == NULL
)
167 errx(1, "login: Audit Error: au_to_subject32() failed");
169 /* We know the subject -- so use its value instead. */
172 if ((tok
= au_to_subject32_ex(uid
, geteuid(), getegid(), uid
,
173 gid
, pid
, pid
, &tid
)) == NULL
)
174 errx(1, "login: Audit Error: au_to_subject32() failed");
178 /* Include the error message. */
179 if ((tok
= au_to_text(errmsg
)) == NULL
)
180 errx(1, "login: Audit Error: au_to_text() failed");
183 if ((tok
= au_to_return32(1, errno
)) == NULL
)
184 errx(1, "login: Audit Error: au_to_return32() failed");
187 if (au_close(aufd
, 1, AUE_login
) == -1)
188 errx(1, "login: Audit Error: au_close() was not committed");
192 * The following tokens are included in the audit record for a logout:
193 * header, subject, return.
200 uid_t uid
= pwd
->pw_uid
;
201 gid_t gid
= pwd
->pw_gid
;
202 pid_t pid
= getpid();
205 /* If we are not auditing, don't cut an audit record; just return. */
206 if (auditon(A_GETCOND
, &au_cond
, sizeof(long)) < 0) {
209 errx(1, "login: Could not determine audit condition");
211 if (au_cond
== AUC_NOAUDIT
)
214 if ((aufd
= au_open()) == -1)
215 errx(1, "login: Audit Error: au_open() failed");
217 /* The subject that is created (euid, egid of the current process). */
218 if ((tok
= au_to_subject32_ex(uid
, geteuid(), getegid(), uid
, gid
, pid
,
220 errx(1, "login: Audit Error: au_to_subject32() failed");
223 if ((tok
= au_to_return32(0, 0)) == NULL
)
224 errx(1, "login: Audit Error: au_to_return32() failed");
227 if (au_close(aufd
, 1, AUE_logout
) == -1)
228 errx(1, "login: Audit Record was not committed.");
231 #endif /* USE_BSM_AUDIT */