]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/login/login_audit.c
This commit was generated by cvs2svn to compensate for changes in r162017,
[FreeBSD/FreeBSD.git] / usr.bin / login / login_audit.c
1 /*
2  * Copyright (c) 2005 Apple Computer, Inc.
3  * All rights reserved.
4  *
5  * @APPLE_BSD_LICENSE_HEADER_START@
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
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.
19  *
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.
30  *
31  * @APPLE_BSD_LICENSE_HEADER_END@
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
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
47 #include "login.h"
48
49 /*
50  * Audit data
51  */
52 static au_tid_t tid;
53
54 /*
55  * The following tokens are included in the audit record for a successful
56  * login: header, subject, return.
57  */
58 void
59 au_login_success(void)
60 {
61         token_t *tok;
62         int aufd;
63         au_mask_t aumask;
64         auditinfo_t auinfo;
65         uid_t uid = pwd->pw_uid;
66         gid_t gid = pwd->pw_gid;
67         pid_t pid = getpid();
68         long au_cond;
69
70         /* If we are not auditing, don't cut an audit record; just return. */
71         if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
72                 if (errno == ENOSYS)
73                         return;
74                 errx(1, "login: Could not determine audit condition");
75         }
76         if (au_cond == AUC_NOAUDIT)
77                 return;
78
79         /* Compute and set the user's preselection mask. */
80         if (au_user_mask(pwd->pw_name, &aumask) == -1)
81                 errx(1, "login: Could not set audit mask\n");
82
83         /* Set the audit info for the user. */
84         auinfo.ai_auid = uid;
85         auinfo.ai_asid = pid;
86         bcopy(&tid, &auinfo.ai_termid, sizeof(auinfo.ai_termid));
87         bcopy(&aumask, &auinfo.ai_mask, sizeof(auinfo.ai_mask));
88         if (setaudit(&auinfo) != 0)
89                 err(1, "login: setaudit failed");
90
91         if ((aufd = au_open()) == -1)
92                 errx(1,"login: Audit Error: au_open() failed");
93
94         if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid, gid, pid,
95             pid, &tid)) == NULL)
96                 errx(1, "login: Audit Error: au_to_subject32() failed");
97         au_write(aufd, tok);
98
99         if ((tok = au_to_return32(0, 0)) == NULL)
100                 errx(1, "login: Audit Error: au_to_return32() failed");
101         au_write(aufd, tok);
102
103         if (au_close(aufd, 1, AUE_login) == -1)
104                 errx(1, "login: Audit Record was not committed.");
105 }
106
107 /*
108  * The following tokens are included in the audit record for failed
109  * login attempts: header, subject, text, return.
110  */
111 void
112 au_login_fail(char *errmsg, int na)
113 {
114         token_t *tok;
115         int aufd;
116         long au_cond;
117         uid_t uid;
118         gid_t gid;
119         pid_t pid = getpid();
120
121         /* If we are not auditing, don't cut an audit record; just return. */
122         if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
123                 if (errno == ENOSYS)
124                         return;
125                 errx(1, "login: Could not determine audit condition");
126         }
127         if (au_cond == AUC_NOAUDIT)
128                 return;
129
130         if ((aufd = au_open()) == -1)
131                 errx(1, "login: Audit Error: au_open() failed");
132
133         if (na) {
134                 /*
135                  * Non attributable event.  Assuming that login is not called
136                  * within a user's session => auid,asid == -1.
137                  */
138                 if ((tok = au_to_subject32(-1, geteuid(), getegid(), -1, -1,
139                     pid, -1, &tid)) == NULL)
140                         errx(1, "login: Audit Error: au_to_subject32() failed");
141         } else {
142                 /* We know the subject -- so use its value instead. */
143                 uid = pwd->pw_uid;
144                 gid = pwd->pw_gid;
145                 if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid,
146                     gid, pid, pid, &tid)) == NULL)
147                         errx(1, "login: Audit Error: au_to_subject32() failed");
148         }
149         au_write(aufd, tok);
150
151         /* Include the error message. */
152         if ((tok = au_to_text(errmsg)) == NULL)
153                 errx(1, "login: Audit Error: au_to_text() failed");
154         au_write(aufd, tok);
155
156         if ((tok = au_to_return32(1, errno)) == NULL)
157                 errx(1, "login: Audit Error: au_to_return32() failed");
158         au_write(aufd, tok);
159
160         if (au_close(aufd, 1, AUE_login) == -1)
161                 errx(1, "login: Audit Error: au_close() was not committed");
162 }
163
164 /*
165  * The following tokens are included in the audit record for a logout:
166  * header, subject, return.
167  */
168 void
169 audit_logout(void)
170 {
171         token_t *tok;
172         int aufd;
173         au_mask_t aumask;
174         auditinfo_t auinfo;
175         uid_t uid = pwd->pw_uid;
176         gid_t gid = pwd->pw_gid;
177         pid_t pid = getpid();
178         long 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(long)) < 0) {
182                 if (errno == ENOSYS)
183                         return;
184                 errx(1, "login: Could not determine audit condition");
185         }
186         if (au_cond == AUC_NOAUDIT)
187                 return;
188
189         if ((aufd = au_open()) == -1)
190                 errx(1, "login: 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, "login: Audit Error: au_to_subject32() failed");
196         au_write(aufd, tok);
197
198         if ((tok = au_to_return32(0, 0)) == NULL)
199                 errx(1, "login: Audit Error: au_to_return32() failed");
200         au_write(aufd, tok);
201
202         if (au_close(aufd, 1, AUE_logout) == -1)
203                 errx(1, "login: Audit Record was not committed.");
204 }