]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/login/login_audit.c
Add two missing eventhandler.h headers
[FreeBSD/FreeBSD.git] / usr.bin / login / login_audit.c
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(int)) < 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 }