4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/param.h>
28 #include <sys/types.h>
31 #include <bsm/audit.h>
32 #include <bsm/libbsm.h>
33 #include <bsm/audit_record.h>
38 * Open an audit record = find a free descriptor and pass it back.
39 * The descriptors are in a "fixed" length array which is extended
40 * whenever it gets full.
42 * Since the expected frequency of copies is expected to be low,
43 * and since realloc loses data if it fails to expand the buffer,
44 * calloc() is used rather than realloc().
48 * AU_TABLE_MAX must be a integer multiple of AU_TABLE_LENGTH
50 #define AU_TABLE_LENGTH 16
51 #define AU_TABLE_MAX 256
53 static token_t
**au_d
;
54 static int au_d_length
= 0; /* current table length */
55 static int au_d_required_length
= AU_TABLE_LENGTH
; /* new table length */
56 static mutex_t mutex_au_d
= DEFAULTMUTEX
;
61 int d
; /* descriptor */
64 (void) mutex_lock(&mutex_au_d
);
66 if (au_d_required_length
> au_d_length
) {
67 au_d_new
= (token_t
**)calloc(au_d_required_length
,
70 if (au_d_new
== NULL
) {
71 au_d_required_length
= au_d_length
;
72 (void) mutex_unlock(&mutex_au_d
);
75 if (au_d_length
> 0) {
76 (void) memcpy(au_d_new
, au_d
, au_d_length
*
81 au_d_length
= au_d_required_length
;
83 for (d
= 0; d
< au_d_length
; d
++) {
84 if (au_d
[d
] == (token_t
*)0) {
85 au_d
[d
] = (token_t
*)&au_d
;
86 (void) mutex_unlock(&mutex_au_d
);
91 * table full; make more room.
92 * AU_TABLE_MAX limits recursion.
93 * Logic here expects AU_TABLE_MAX to be multiple of AU_TABLE_LENGTH
95 if (au_d_length
>= AU_TABLE_MAX
) {
96 (void) mutex_unlock(&mutex_au_d
);
99 au_d_required_length
+= AU_TABLE_LENGTH
;
100 (void) mutex_unlock(&mutex_au_d
);
106 * Write to an audit descriptor.
107 * Add the mbuf to the descriptor chain and free the chain passed in.
111 au_write(int d
, token_t
*m
)
117 if (m
== (token_t
*)0)
119 (void) mutex_lock(&mutex_au_d
);
120 if ((d
>= au_d_length
) || (au_d
[d
] == (token_t
*)0)) {
121 (void) mutex_unlock(&mutex_au_d
);
123 } else if (au_d
[d
] == (token_t
*)&au_d
) {
125 (void) mutex_unlock(&mutex_au_d
);
128 for (mp
= au_d
[d
]; mp
->tt_next
!= (token_t
*)0; mp
= mp
->tt_next
)
131 (void) mutex_unlock(&mutex_au_d
);
136 * Close an audit descriptor.
137 * Use the second parameter to indicate if it should be written or not.
140 au_close(int d
, int right
, au_event_t e_type
)
143 struct timeval now
; /* current time */
144 adr_t adr
; /* adr header */
145 auditinfo_addr_t audit_info
;
146 au_tid_addr_t
*host_info
= &audit_info
.ai_termid
;
147 token_t
*dchain
; /* mbuf chain which is the tokens */
148 token_t
*record
; /* mbuf chain which is the record */
149 char data_header
; /* token type */
150 char version
; /* token version */
151 char *buffer
; /* to build record into */
152 int byte_count
; /* bytes in the record */
155 (void) mutex_lock(&mutex_au_d
);
156 if (d
< 0 || d
>= au_d_length
||
157 ((dchain
= au_d
[d
]) == (token_t
*)0)) {
158 (void) mutex_unlock(&mutex_au_d
);
162 au_d
[d
] = (token_t
*)0;
164 if (dchain
== (token_t
*)&au_d
) {
165 (void) mutex_unlock(&mutex_au_d
);
169 * If not to be written toss the record
172 while (dchain
!= (token_t
*)0) {
174 dchain
= dchain
->tt_next
;
175 free(record
->tt_data
);
178 (void) mutex_unlock(&mutex_au_d
);
183 * Count up the bytes used in the record.
185 byte_count
= sizeof (char) * 2 + sizeof (short) * 2 +
186 sizeof (int32_t) + sizeof (struct timeval
);
188 for (record
= dchain
; record
!= (token_t
*)0;
189 record
= record
->tt_next
) {
190 byte_count
+= record
->tt_size
;
194 #define HEADER_ID AUT_HEADER64
195 #define HEADER_ID_EX AUT_HEADER64_EX
197 #define HEADER_ID AUT_HEADER32
198 #define HEADER_ID_EX AUT_HEADER32_EX
201 /* Use the extended headed if our host address can be determined. */
203 data_header
= HEADER_ID
; /* Assume the worst */
204 if (auditon(A_GETKAUDIT
, (caddr_t
)&audit_info
,
205 sizeof (audit_info
)) == 0) {
208 if (host_info
->at_type
== AU_IPv6
)
209 have_valid_addr
= IN6_IS_ADDR_UNSPECIFIED(
210 (in6_addr_t
*)host_info
->at_addr
) ? 0 : 1;
212 have_valid_addr
= (host_info
->at_addr
[0] ==
213 htonl(INADDR_ANY
)) ? 0 : 1;
215 if (have_valid_addr
) {
216 data_header
= HEADER_ID_EX
;
217 byte_count
+= sizeof (int32_t) + host_info
->at_type
;
224 if ((buffer
= malloc((size_t)byte_count
)) == NULL
) {
225 /* free the token chain */
226 while (dchain
!= (token_t
*)0) {
228 dchain
= dchain
->tt_next
;
229 free(record
->tt_data
);
232 (void) mutex_unlock(&mutex_au_d
);
235 (void) gettimeofday(&now
, NULL
);
236 version
= TOKEN_VERSION
;
238 adr_start(&adr
, buffer
);
239 adr_char(&adr
, &data_header
, 1);
240 adr_int32(&adr
, (int32_t *)&byte_count
, 1);
241 adr_char(&adr
, &version
, 1);
242 adr_ushort(&adr
, &e_type
, 1);
243 adr_ushort(&adr
, &e_mod
, 1);
244 if (data_header
== HEADER_ID_EX
) {
245 adr_int32(&adr
, (int32_t *)&host_info
->at_type
, 1);
246 adr_char(&adr
, (char *)&host_info
->at_addr
[0],
247 (int)host_info
->at_type
);
250 adr_int64(&adr
, (int64_t *)&now
, 2);
252 adr_int32(&adr
, (int32_t *)&now
, 2);
255 * Tack on the data, and free the tokens.
256 * We're not supposed to know how adr works, but ...
258 while (dchain
!= (token_t
*)0) {
259 (void) memcpy(adr
.adr_now
, dchain
->tt_data
, dchain
->tt_size
);
260 adr
.adr_now
+= dchain
->tt_size
;
262 dchain
= dchain
->tt_next
;
263 free(record
->tt_data
);
267 * Send it down to the system
269 v
= audit((caddr_t
)buffer
, byte_count
);
271 (void) mutex_unlock(&mutex_au_d
);