1005d3febSMarek Pospisil /*
2005d3febSMarek Pospisil * CDDL HEADER START
3005d3febSMarek Pospisil *
4005d3febSMarek Pospisil * The contents of this file are subject to the terms of the
5005d3febSMarek Pospisil * Common Development and Distribution License (the "License").
6005d3febSMarek Pospisil * You may not use this file except in compliance with the License.
7005d3febSMarek Pospisil *
8005d3febSMarek Pospisil * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9005d3febSMarek Pospisil * or http://www.opensolaris.org/os/licensing.
10005d3febSMarek Pospisil * See the License for the specific language governing permissions
11005d3febSMarek Pospisil * and limitations under the License.
12005d3febSMarek Pospisil *
13005d3febSMarek Pospisil * When distributing Covered Code, include this CDDL HEADER in each
14005d3febSMarek Pospisil * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15005d3febSMarek Pospisil * If applicable, add the following below this CDDL HEADER, with the
16005d3febSMarek Pospisil * fields enclosed by brackets "[]" replaced with your own identifying
17005d3febSMarek Pospisil * information: Portions Copyright [yyyy] [name of copyright owner]
18005d3febSMarek Pospisil *
19005d3febSMarek Pospisil * CDDL HEADER END
20005d3febSMarek Pospisil */
21005d3febSMarek Pospisil /*
22005d3febSMarek Pospisil * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23005d3febSMarek Pospisil * Use is subject to license terms.
24005d3febSMarek Pospisil */
25005d3febSMarek Pospisil
26005d3febSMarek Pospisil
27005d3febSMarek Pospisil #include <c2/audit.h>
28005d3febSMarek Pospisil #include <c2/audit_kernel.h>
29005d3febSMarek Pospisil #include <c2/audit_record.h>
30005d3febSMarek Pospisil #include <sys/kmem.h>
31005d3febSMarek Pospisil #include <sys/param.h>
32005d3febSMarek Pospisil #include <sys/systm.h>
33005d3febSMarek Pospisil #include <sys/taskq.h>
34005d3febSMarek Pospisil #include <sys/t_lock.h>
35005d3febSMarek Pospisil #include <sys/thread.h>
36005d3febSMarek Pospisil #include <sys/types.h>
37005d3febSMarek Pospisil #include <sys/zone.h>
38005d3febSMarek Pospisil
39005d3febSMarek Pospisil zone_key_t au_zone_key;
40005d3febSMarek Pospisil
41005d3febSMarek Pospisil /*ARGSUSED*/
42005d3febSMarek Pospisil static void *
au_zone_init(zoneid_t zone)43005d3febSMarek Pospisil au_zone_init(zoneid_t zone)
44005d3febSMarek Pospisil {
45005d3febSMarek Pospisil au_kcontext_t *kctx = kmem_zalloc(sizeof (au_kcontext_t), KM_SLEEP);
46005d3febSMarek Pospisil static au_kcontext_t *global_kctx = NULL;
47005d3febSMarek Pospisil
48005d3febSMarek Pospisil /*
49005d3febSMarek Pospisil * INGLOBALZONE(curproc) is invalid at this point, so check for
50005d3febSMarek Pospisil * zone 0
51005d3febSMarek Pospisil */
52005d3febSMarek Pospisil
53005d3febSMarek Pospisil if (zone == 0) {
54005d3febSMarek Pospisil global_kctx = kctx;
55005d3febSMarek Pospisil global_zone->zone_audit_kctxt = kctx;
56005d3febSMarek Pospisil } else {
57005d3febSMarek Pospisil kctx->auk_policy = global_kctx->auk_policy;
58005d3febSMarek Pospisil curproc->p_zone->zone_audit_kctxt = kctx;
59005d3febSMarek Pospisil }
60005d3febSMarek Pospisil kctx->auk_valid = AUK_VALID;
61005d3febSMarek Pospisil kctx->auk_zid = zone;
62005d3febSMarek Pospisil
63005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type = AU_IPv4;
64005d3febSMarek Pospisil kctx->auk_info.ai_auid = AU_NOAUDITID;
65005d3febSMarek Pospisil kctx->auk_auditstate = AUC_INIT_AUDIT;
66005d3febSMarek Pospisil
67005d3febSMarek Pospisil /* setup defaults for audit queue flow control */
68005d3febSMarek Pospisil kctx->auk_queue.hiwater = AQ_HIWATER;
69005d3febSMarek Pospisil kctx->auk_queue.lowater = AQ_LOWATER;
70005d3febSMarek Pospisil kctx->auk_queue.bufsz = AQ_BUFSZ;
71005d3febSMarek Pospisil kctx->auk_queue.buflen = AQ_BUFSZ;
72005d3febSMarek Pospisil kctx->auk_queue.delay = AQ_DELAY;
73005d3febSMarek Pospisil
74005d3febSMarek Pospisil /* statistics per zone */
75005d3febSMarek Pospisil kctx->auk_statistics.as_version = TOKEN_VERSION;
76005d3febSMarek Pospisil kctx->auk_statistics.as_numevent = MAX_KEVENTS;
77005d3febSMarek Pospisil
78005d3febSMarek Pospisil /* door IO buffer: */
79005d3febSMarek Pospisil kctx->auk_dbuffer =
80005d3febSMarek Pospisil kmem_alloc(AU_DBUF_HEADER + kctx->auk_queue.bufsz, KM_SLEEP);
81005d3febSMarek Pospisil
82005d3febSMarek Pospisil /* locks and cv's */
83005d3febSMarek Pospisil
84005d3febSMarek Pospisil mutex_init(&(kctx->auk_eagain_mutex), NULL, MUTEX_DEFAULT, NULL);
85005d3febSMarek Pospisil cv_init(&(kctx->auk_eagain_cv), NULL, CV_DRIVER, NULL);
86005d3febSMarek Pospisil
87005d3febSMarek Pospisil mutex_init(&(kctx->auk_svc_lock), NULL, MUTEX_DEFAULT, NULL);
88005d3febSMarek Pospisil
89005d3febSMarek Pospisil mutex_init(&(kctx->auk_queue.lock), NULL, MUTEX_DEFAULT, NULL);
90005d3febSMarek Pospisil cv_init(&(kctx->auk_queue.write_cv), NULL, CV_DRIVER, NULL);
91005d3febSMarek Pospisil cv_init(&(kctx->auk_queue.read_cv), NULL, CV_DRIVER, NULL);
92005d3febSMarek Pospisil
93005d3febSMarek Pospisil return (kctx);
94005d3febSMarek Pospisil }
95005d3febSMarek Pospisil
96005d3febSMarek Pospisil /*ARGSUSED*/
97005d3febSMarek Pospisil static void
au_zone_shutdown(zoneid_t zone,void * arg)98005d3febSMarek Pospisil au_zone_shutdown(zoneid_t zone, void *arg)
99005d3febSMarek Pospisil {
100005d3febSMarek Pospisil au_kcontext_t *kctx = arg;
101005d3febSMarek Pospisil
102005d3febSMarek Pospisil if (audit_active == C2AUDIT_LOADED && (kctx->auk_zid == GLOBAL_ZONEID ||
103005d3febSMarek Pospisil (audit_policy | AUDIT_PERZONE)) && (kctx->auk_current_vp != NULL))
104005d3febSMarek Pospisil (void) au_doormsg(kctx, AU_DBUF_SHUTDOWN, NULL);
105005d3febSMarek Pospisil
106005d3febSMarek Pospisil kctx->auk_valid = AUK_INVALID;
107005d3febSMarek Pospisil
108005d3febSMarek Pospisil /* shutdown the output thread if it is still running */
109005d3febSMarek Pospisil kctx->auk_auditstate = AUC_NOAUDIT;
110005d3febSMarek Pospisil
111005d3febSMarek Pospisil if (kctx->auk_output_active) {
112005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock));
113005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.read_cv));
114005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock));
115005d3febSMarek Pospisil
116005d3febSMarek Pospisil taskq_destroy(kctx->auk_taskq);
117005d3febSMarek Pospisil }
118005d3febSMarek Pospisil }
119005d3febSMarek Pospisil
120005d3febSMarek Pospisil /*ARGSUSED*/
121005d3febSMarek Pospisil static void
au_zone_destroy(zoneid_t zone,void * arg)122005d3febSMarek Pospisil au_zone_destroy(zoneid_t zone, void *arg)
123005d3febSMarek Pospisil {
124005d3febSMarek Pospisil au_kcontext_t *kctx = arg;
125005d3febSMarek Pospisil
126005d3febSMarek Pospisil ASSERT(kctx->auk_auditstate == AUC_NOAUDIT);
127005d3febSMarek Pospisil
128005d3febSMarek Pospisil mutex_destroy(&(kctx->auk_eagain_mutex));
129005d3febSMarek Pospisil cv_destroy(&(kctx->auk_eagain_cv));
130005d3febSMarek Pospisil
131005d3febSMarek Pospisil mutex_destroy(&(kctx->auk_svc_lock));
132005d3febSMarek Pospisil
133005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock));
134005d3febSMarek Pospisil if (kctx->auk_queue.head != NULL) {
135005d3febSMarek Pospisil au_free_rec(kctx->auk_queue.head);
136005d3febSMarek Pospisil }
137005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock));
138005d3febSMarek Pospisil
139005d3febSMarek Pospisil mutex_destroy(&(kctx->auk_queue.lock));
140005d3febSMarek Pospisil
141005d3febSMarek Pospisil cv_destroy(&(kctx->auk_queue.write_cv));
142005d3febSMarek Pospisil cv_destroy(&(kctx->auk_queue.read_cv));
143005d3febSMarek Pospisil
144*5562c04eSMarek Pospisil kmem_free(kctx->auk_dbuffer, AU_DBUF_HEADER + kctx->auk_queue.buflen);
145005d3febSMarek Pospisil
146005d3febSMarek Pospisil kmem_free(kctx, sizeof (au_kcontext_t));
147005d3febSMarek Pospisil }
148005d3febSMarek Pospisil
149005d3febSMarek Pospisil void
au_zone_setup()150005d3febSMarek Pospisil au_zone_setup()
151005d3febSMarek Pospisil {
152005d3febSMarek Pospisil zone_key_create(&au_zone_key, au_zone_init, au_zone_shutdown,
153005d3febSMarek Pospisil au_zone_destroy);
154005d3febSMarek Pospisil
155005d3febSMarek Pospisil }
156005d3febSMarek Pospisil
157005d3febSMarek Pospisil int
au_zone_getstate(const au_kcontext_t * context)158005d3febSMarek Pospisil au_zone_getstate(const au_kcontext_t *context)
159005d3febSMarek Pospisil {
160005d3febSMarek Pospisil au_kcontext_t *tcontext;
161005d3febSMarek Pospisil
162005d3febSMarek Pospisil if (context != NULL)
163005d3febSMarek Pospisil return (context->auk_auditstate);
164005d3febSMarek Pospisil tcontext = GET_KCTX_PZ;
165005d3febSMarek Pospisil return (tcontext->auk_auditstate);
166005d3febSMarek Pospisil }
167