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.
27 #include <netinet/in.h>
29 #include <sys/errno.h>
30 #include <sys/mutex.h>
31 #include <sys/param.h>
32 #include <sys/socket.h>
34 #include <sys/types.h>
39 #include <tsol/label.h>
40 #include <bsm/audit.h>
41 #include <bsm/libbsm.h>
42 #include <bsm/audit_uevents.h>
43 #include <bsm/audit_record.h>
45 #define AUC_NEVER -2 /* audit module not loaded */
47 /* Private Functions */
48 static int selected(au_event_t
, au_mask_t
*, int);
51 int aug_na_selected();
53 /* Global Variables */
54 static au_id_t aug_auid
; /* auid of user writing audit record */
55 static uid_t aug_uid
; /* uid of user writing audit record */
56 static uid_t aug_euid
; /* euid of user writing audit record */
57 static gid_t aug_gid
; /* gid of user writing audit record */
58 static gid_t aug_egid
; /* euid of user writing audit record */
59 static pid_t aug_pid
; /* pid of user writing audit record */
60 static au_tid_addr_t aug_tid
; /* tid of user writing audit record */
61 static int aug_na
; /* 0 if event is attributable */
62 static au_mask_t aug_namask
; /* not attributable flags */
63 static au_event_t aug_event
; /* id of event being audited */
64 static int aug_sorf
; /* success or failure of aug_event */
65 static char *aug_text
; /* misc text to be written to trail */
66 static char *aug_text1
; /* misc text to be written to trail */
67 static char *aug_text2
; /* misc text to be written to trail */
68 static au_asid_t aug_asid
; /* asid of process writing record */
69 static int (*aug_afunc
)(); /* write additional tokens if needed */
70 static char *aug_path
; /* path token */
71 static uint32_t aug_policy
; /* kernel audit policy */
75 * Return 1 if audit module not loaded.
78 * The argument, force, should be set to 1 for long-lived processes
79 * like some daemons. Force should be set to 0 for most programs.
85 static int auc
= AUC_UNSET
;
88 if (auc
== AUC_UNSET
|| force
) {
89 if (auditon(A_GETCOND
, (caddr_t
)&cond
, sizeof (cond
))) {
95 return (auc
== AUC_NEVER
);
100 * Initialize global variables.
105 aug_auid
= (uid_t
)-1;
107 aug_euid
= (uid_t
)-1;
109 aug_egid
= (gid_t
)-1;
112 aug_tid
.at_type
= AU_IPv4
;
113 aug_tid
.at_addr
[0] = 0;
114 aug_tid
.at_addr
[1] = 0;
115 aug_tid
.at_addr
[2] = 0;
116 aug_tid
.at_addr
[3] = 0;
117 aug_namask
.am_success
= AU_MASK_ALL
;
118 aug_namask
.am_failure
= AU_MASK_ALL
;
125 aug_asid
= (au_asid_t
)(-1);
132 * Return the raw device number of the port to which the
133 * current process is attached (assumed to be attached
134 * through file descriptor 0) or 0 if can't stat the port.
144 if (ttyn
== 0 || *ttyn
== '\0') {
148 rc
= stat(ttyn
, &sb
);
154 return ((dev_t
)sb
.st_rdev
);
159 * Return internet address of host hostname,
160 * or 0 if can't do lookup.
164 aug_get_machine(const char *hostname
, uint32_t *buf
, uint32_t *type
)
170 err
= getaddrinfo(hostname
, NULL
, NULL
, &ai
);
174 switch (ai
->ai_family
) {
177 p
= &((struct sockaddr_in
*)ai
->ai_addr
)->sin_addr
,
178 (void) memcpy(buf
, p
,
179 sizeof (((struct sockaddr_in
*)0)->sin_addr
));
184 p
= &((struct sockaddr_in6
*)ai
->ai_addr
)->sin6_addr
,
185 (void) memcpy(buf
, p
,
186 sizeof (((struct sockaddr_in6
*)0)->sin6_addr
));
199 aug_save_auid(au_id_t id
)
205 aug_save_uid(uid_t id
)
211 aug_save_euid(uid_t id
)
217 aug_save_gid(gid_t id
)
223 aug_save_egid(gid_t id
)
229 aug_save_pid(pid_t id
)
235 aug_save_asid(au_asid_t id
)
241 aug_save_afunc(int (*afunc
)())
247 aug_save_tid(dev_t port
, int machine
)
249 aug_tid
.at_port
= port
;
250 aug_tid
.at_type
= AU_IPv4
;
251 aug_tid
.at_addr
[0] = machine
;
255 aug_save_tid_ex(dev_t port
, uint32_t *machine
, uint32_t type
)
259 aug_tid
.at_port
= port
;
260 if ((type
!= AU_IPv4
) && (type
!= AU_IPv6
))
263 aug_tid
.at_type
= type
;
264 for (i
= 0; i
< (type
/4); i
++)
265 aug_tid
.at_addr
[i
] = machine
[i
];
273 if (getaudit_addr(&ai
, sizeof (ai
)))
276 aug_save_auid(ai
.ai_auid
);
277 aug_save_euid(geteuid());
278 aug_save_egid(getegid());
279 aug_save_uid(getuid());
280 aug_save_gid(getgid());
281 aug_save_pid(getpid());
282 aug_save_asid(ai
.ai_asid
);
283 aug_save_tid_ex(ai
.ai_termid
.at_port
,
284 ai
.ai_termid
.at_addr
,
285 ai
.ai_termid
.at_type
);
291 * Save the namask using the naflags entry in the audit_control file.
292 * Return 0 if successful.
293 * Return -1, and don't change the namask, if failed.
294 * Side Effect: Sets aug_na to -1 if error, 1 if successful.
304 * get non-attributable system event mask from kernel.
306 if (auditon(A_GETKMASK
, (caddr_t
)&mask
, sizeof (mask
)) != 0) {
310 aug_namask
.am_success
= mask
.am_success
;
311 aug_namask
.am_failure
= mask
.am_failure
;
317 aug_save_event(au_event_t id
)
323 aug_save_sorf(int sorf
)
329 aug_save_text(char *s
)
331 if (aug_text
!= NULL
)
336 aug_text
= strdup(s
);
340 aug_save_text1(char *s
)
342 if (aug_text1
!= NULL
)
347 aug_text1
= strdup(s
);
351 aug_save_text2(char *s
)
353 if (aug_text2
!= NULL
)
358 aug_text2
= strdup(s
);
362 aug_save_na(int flag
)
368 aug_save_path(char *s
)
370 if (aug_path
!= NULL
)
374 aug_path
= strdup(s
);
382 if (auditon(A_GETPOLICY
, (caddr_t
)&policy
, sizeof (policy
))) {
391 * Cut and audit record if it is selected.
392 * Return 0, if successfully written.
393 * Return 0, if not written, and not expected to write.
394 * Return -1, if not written because of unexpected error.
401 if (cannot_audit(0)) {
406 if (!aug_na_selected()) {
409 } else if (!aug_selected()) {
413 if ((ad
= au_open()) == -1) {
417 (void) au_write(ad
, au_to_subject_ex(aug_auid
, aug_euid
, aug_egid
,
418 aug_uid
, aug_gid
, aug_pid
, aug_asid
, &aug_tid
));
419 if (is_system_labeled())
420 (void) au_write(ad
, au_to_mylabel());
421 if (aug_policy
& AUDIT_GROUP
) {
423 int maxgrp
= getgroups(0, NULL
);
424 gid_t
*grplst
= alloca(maxgrp
* sizeof (gid_t
));
426 if ((ng
= getgroups(maxgrp
, grplst
)) > 0) {
427 (void) au_write(ad
, au_to_newgroups(ng
, grplst
));
430 if (aug_text
!= NULL
) {
431 (void) au_write(ad
, au_to_text(aug_text
));
433 if (aug_text1
!= NULL
) {
434 (void) au_write(ad
, au_to_text(aug_text1
));
436 if (aug_text2
!= NULL
) {
437 (void) au_write(ad
, au_to_text(aug_text2
));
439 if (aug_path
!= NULL
) {
440 (void) au_write(ad
, au_to_path(aug_path
));
442 if (aug_afunc
!= NULL
) {
446 (void) au_write(ad
, au_to_return64((aug_sorf
== 0) ? 0 : -1,
449 (void) au_write(ad
, au_to_return32((aug_sorf
== 0) ? 0 : -1,
452 if (au_close(ad
, 1, aug_event
) < 0) {
453 (void) au_close(ad
, 0, 0);
467 return (selected(aug_event
, &aug_namask
, aug_sorf
));
473 auditinfo_addr_t mask
;
475 if (aug_uid
> MAXEPHUID
) {
476 (void) aug_save_namask();
477 return (aug_na_selected());
479 if (getaudit_addr(&mask
, sizeof (mask
))) {
483 return (selected(aug_event
, &mask
.ai_mask
, aug_sorf
));
487 selected(au_event_t e
, au_mask_t
*m
, int sorf
)
492 prs_sorf
= AU_PRS_SUCCESS
;
493 } else if (sorf
== -1) {
494 prs_sorf
= AU_PRS_FAILURE
;
496 prs_sorf
= AU_PRS_BOTH
;
499 return (au_preselect(e
, m
, prs_sorf
, AU_PRS_REREAD
));