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]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
28 #include <netinet/in.h>
30 #include <sys/errno.h>
31 #include <sys/mutex.h>
32 #include <sys/param.h>
33 #include <sys/socket.h>
35 #include <sys/types.h>
40 #include <sys/smedia.h>
42 #include <bsm/audit.h>
43 #include <bsm/libbsm.h>
44 #include <bsm/audit_uevents.h>
45 #include <bsm/audit_record.h>
47 /* Private Functions */
48 static int selected(au_event_t
, au_mask_t
*, int);
50 static int audit_selected(door_data_t
*);
51 static int audit_na_selected(door_data_t
*);
52 static int audit_save_namask(door_data_t
*door_dp
);
53 static int audit_save_policy(door_data_t
*door_dp
);
57 * Return 1 if audit module is loaded.
64 static int auc
= AUC_UNSET
;
67 if (auditon(A_GETCOND
, (caddr_t
)&cond
, sizeof (cond
))) {
72 if (auc
== AUC_DISABLED
)
78 audit_save_policy(door_data_t
*door_dp
)
82 if (auditon(A_GETPOLICY
, (caddr_t
)&policy
, sizeof (policy
))) {
85 door_dp
->audit_policy
= policy
;
91 * Initialize variables.
94 audit_init(door_data_t
*door_dp
)
96 door_dp
->audit_auid
= (uid_t
)-1;
97 door_dp
->audit_uid
= (uid_t
)-1;
98 door_dp
->audit_euid
= (uid_t
)-1;
99 door_dp
->audit_gid
= (gid_t
)-1;
100 door_dp
->audit_egid
= (gid_t
)-1;
101 door_dp
->audit_pid
= -1;
102 door_dp
->audit_tid
.at_port
= 0;
103 door_dp
->audit_tid
.at_type
= 0;
104 door_dp
->audit_tid
.at_addr
[0] = 0;
105 door_dp
->audit_tid
.at_addr
[1] = 0;
106 door_dp
->audit_tid
.at_addr
[2] = 0;
107 door_dp
->audit_tid
.at_addr
[3] = 0;
108 door_dp
->audit_namask
.am_success
= (int)-1;
109 door_dp
->audit_namask
.am_failure
= (int)-1;
110 door_dp
->audit_event
= 0;
111 door_dp
->audit_sorf
= -2;
112 door_dp
->audit_user
= NULL
;
113 door_dp
->audit_text
[0] = '\0';
114 door_dp
->audit_text1
[0] = '\0';
115 door_dp
->audit_na
= 0;
116 door_dp
->audit_asid
= (au_asid_t
)(-1);
117 door_dp
->audit_path
= NULL
;
121 audit_save_me(door_data_t
*door_dp
)
123 door_cred_t client_cred
;
127 ret_val
= door_cred(&client_cred
);
130 door_dp
->audit_ap
.ap_pid
= client_cred
.dc_pid
;
131 ret_val
= auditon(A_GETPINFO_ADDR
, (caddr_t
)&door_dp
->audit_ap
,
132 sizeof (door_dp
->audit_ap
));
136 door_dp
->audit_auid
= door_dp
->audit_ap
.ap_auid
;
137 door_dp
->audit_euid
= client_cred
.dc_euid
;
138 door_dp
->audit_egid
= client_cred
.dc_egid
;
139 door_dp
->audit_uid
= client_cred
.dc_ruid
;
140 door_dp
->audit_gid
= client_cred
.dc_rgid
;
141 door_dp
->audit_pid
= client_cred
.dc_pid
;
142 door_dp
->audit_asid
= door_dp
->audit_ap
.ap_asid
;
143 door_dp
->audit_tid
.at_port
= door_dp
->audit_ap
.ap_termid
.at_port
;
144 door_dp
->audit_tid
.at_type
= door_dp
->audit_ap
.ap_termid
.at_type
;
145 for (i
= 0; i
< (door_dp
->audit_ap
.ap_termid
.at_type
/4); i
++)
146 door_dp
->audit_tid
.at_addr
[i
] =
147 door_dp
->audit_ap
.ap_termid
.at_addr
[i
];
148 (void) audit_save_policy(door_dp
);
153 * audit_save_namask():
154 * Save the namask using the naflags entry in the audit_control file.
155 * Return 0 if successful.
156 * Return -1, and don't change the namask, if failed.
157 * Side Effect: Sets audit_na to -1 if error, 1 if successful.
160 audit_save_namask(door_data_t
*door_dp
)
164 door_dp
->audit_na
= -1;
167 * get non-attributable system event mask from kernel.
169 if (auditon(A_GETKMASK
, (caddr_t
)&mask
, sizeof (mask
)) != 0) {
173 door_dp
->audit_namask
.am_success
= mask
.am_success
;
174 door_dp
->audit_namask
.am_failure
= mask
.am_failure
;
175 door_dp
->audit_na
= 1;
181 * Cut and audit record if it is selected.
182 * Return 0, if successfully written.
183 * Return 0, if not written, and not expected to write.
184 * Return -1, if not written because of unexpected error.
187 audit_audit(door_data_t
*door_dp
)
191 if (can_audit() == 0) {
195 if (door_dp
->audit_na
) {
196 if (!audit_na_selected(door_dp
)) {
199 } else if (!audit_selected(door_dp
)) {
203 if ((ad
= au_open()) == -1) {
207 (void) au_write(ad
, au_to_subject_ex(door_dp
->audit_auid
,
210 door_dp
->audit_uid
, door_dp
->audit_gid
, door_dp
->audit_pid
,
211 door_dp
->audit_asid
, &door_dp
->audit_tid
));
212 if (door_dp
->audit_policy
& AUDIT_GROUP
) {
215 int maxgrp
= getgroups(0, NULL
);
216 gid_t
*grplst
= alloca(maxgrp
* sizeof (gid_t
));
218 if ((ng
= getgroups(maxgrp
, grplst
))) {
219 (void) au_write(ad
, au_to_newgroups(ng
, grplst
));
222 if (strlen(door_dp
->audit_text
) != 0) {
223 (void) au_write(ad
, au_to_text(door_dp
->audit_text
));
225 if (strlen(door_dp
->audit_text1
) != 0) {
226 (void) au_write(ad
, au_to_text(door_dp
->audit_text1
));
228 if (door_dp
->audit_path
!= NULL
) {
229 (void) au_write(ad
, au_to_path(door_dp
->audit_path
));
232 (void) au_write(ad
, au_to_return64((door_dp
->audit_sorf
== 0) ? 0 : -1,
233 (int64_t)door_dp
->audit_sorf
));
235 (void) au_write(ad
, au_to_return32((door_dp
->audit_sorf
== 0) ? 0 : -1,
236 (int32_t)door_dp
->audit_sorf
));
238 if (au_close(ad
, 1, door_dp
->audit_event
) < 0) {
239 (void) au_close(ad
, 0, 0);
247 audit_na_selected(door_data_t
*door_dp
)
249 if (door_dp
->audit_na
== -1) {
253 return (selected(door_dp
->audit_event
,
254 &door_dp
->audit_namask
, door_dp
->audit_sorf
));
258 audit_selected(door_data_t
*door_dp
)
261 if (door_dp
->audit_uid
> MAXUID
) {
262 (void) audit_save_namask(door_dp
);
263 return (audit_na_selected(door_dp
));
266 return (selected(door_dp
->audit_event
,
267 &door_dp
->audit_ap
.ap_mask
, door_dp
->audit_sorf
));
271 selected(au_event_t e
, au_mask_t
*m
, int sorf
)
276 prs_sorf
= AU_PRS_SUCCESS
;
277 } else if (sorf
== -1) {
278 prs_sorf
= AU_PRS_FAILURE
;
280 prs_sorf
= AU_PRS_BOTH
;
283 return (au_preselect(e
, m
, prs_sorf
, AU_PRS_REREAD
));