111861SMarek.Pospisil@Sun.COM /*
211861SMarek.Pospisil@Sun.COM * CDDL HEADER START
311861SMarek.Pospisil@Sun.COM *
411861SMarek.Pospisil@Sun.COM * The contents of this file are subject to the terms of the
511861SMarek.Pospisil@Sun.COM * Common Development and Distribution License (the "License").
611861SMarek.Pospisil@Sun.COM * You may not use this file except in compliance with the License.
711861SMarek.Pospisil@Sun.COM *
811861SMarek.Pospisil@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911861SMarek.Pospisil@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011861SMarek.Pospisil@Sun.COM * See the License for the specific language governing permissions
1111861SMarek.Pospisil@Sun.COM * and limitations under the License.
1211861SMarek.Pospisil@Sun.COM *
1311861SMarek.Pospisil@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411861SMarek.Pospisil@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511861SMarek.Pospisil@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611861SMarek.Pospisil@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711861SMarek.Pospisil@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811861SMarek.Pospisil@Sun.COM *
1911861SMarek.Pospisil@Sun.COM * CDDL HEADER END
2011861SMarek.Pospisil@Sun.COM */
2111861SMarek.Pospisil@Sun.COM /*
2211861SMarek.Pospisil@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
2311861SMarek.Pospisil@Sun.COM * Use is subject to license terms.
2411861SMarek.Pospisil@Sun.COM */
2511861SMarek.Pospisil@Sun.COM
2611861SMarek.Pospisil@Sun.COM
2711861SMarek.Pospisil@Sun.COM #include <c2/audit.h>
2811861SMarek.Pospisil@Sun.COM #include <c2/audit_kernel.h>
2911861SMarek.Pospisil@Sun.COM #include <c2/audit_record.h>
3011861SMarek.Pospisil@Sun.COM #include <sys/kmem.h>
3111861SMarek.Pospisil@Sun.COM #include <sys/param.h>
3211861SMarek.Pospisil@Sun.COM #include <sys/systm.h>
3311861SMarek.Pospisil@Sun.COM #include <sys/taskq.h>
3411861SMarek.Pospisil@Sun.COM #include <sys/t_lock.h>
3511861SMarek.Pospisil@Sun.COM #include <sys/thread.h>
3611861SMarek.Pospisil@Sun.COM #include <sys/types.h>
3711861SMarek.Pospisil@Sun.COM #include <sys/zone.h>
3811861SMarek.Pospisil@Sun.COM
3911861SMarek.Pospisil@Sun.COM zone_key_t au_zone_key;
4011861SMarek.Pospisil@Sun.COM
4111861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
4211861SMarek.Pospisil@Sun.COM static void *
au_zone_init(zoneid_t zone)4311861SMarek.Pospisil@Sun.COM au_zone_init(zoneid_t zone)
4411861SMarek.Pospisil@Sun.COM {
4511861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = kmem_zalloc(sizeof (au_kcontext_t), KM_SLEEP);
4611861SMarek.Pospisil@Sun.COM static au_kcontext_t *global_kctx = NULL;
4711861SMarek.Pospisil@Sun.COM
4811861SMarek.Pospisil@Sun.COM /*
4911861SMarek.Pospisil@Sun.COM * INGLOBALZONE(curproc) is invalid at this point, so check for
5011861SMarek.Pospisil@Sun.COM * zone 0
5111861SMarek.Pospisil@Sun.COM */
5211861SMarek.Pospisil@Sun.COM
5311861SMarek.Pospisil@Sun.COM if (zone == 0) {
5411861SMarek.Pospisil@Sun.COM global_kctx = kctx;
5511861SMarek.Pospisil@Sun.COM global_zone->zone_audit_kctxt = kctx;
5611861SMarek.Pospisil@Sun.COM } else {
5711861SMarek.Pospisil@Sun.COM kctx->auk_policy = global_kctx->auk_policy;
5811861SMarek.Pospisil@Sun.COM curproc->p_zone->zone_audit_kctxt = kctx;
5911861SMarek.Pospisil@Sun.COM }
6011861SMarek.Pospisil@Sun.COM kctx->auk_valid = AUK_VALID;
6111861SMarek.Pospisil@Sun.COM kctx->auk_zid = zone;
6211861SMarek.Pospisil@Sun.COM
6311861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_type = AU_IPv4;
6411861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_auid = AU_NOAUDITID;
6511861SMarek.Pospisil@Sun.COM kctx->auk_auditstate = AUC_INIT_AUDIT;
6611861SMarek.Pospisil@Sun.COM
6711861SMarek.Pospisil@Sun.COM /* setup defaults for audit queue flow control */
6811861SMarek.Pospisil@Sun.COM kctx->auk_queue.hiwater = AQ_HIWATER;
6911861SMarek.Pospisil@Sun.COM kctx->auk_queue.lowater = AQ_LOWATER;
7011861SMarek.Pospisil@Sun.COM kctx->auk_queue.bufsz = AQ_BUFSZ;
7111861SMarek.Pospisil@Sun.COM kctx->auk_queue.buflen = AQ_BUFSZ;
7211861SMarek.Pospisil@Sun.COM kctx->auk_queue.delay = AQ_DELAY;
7311861SMarek.Pospisil@Sun.COM
7411861SMarek.Pospisil@Sun.COM /* statistics per zone */
7511861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_version = TOKEN_VERSION;
7611861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_numevent = MAX_KEVENTS;
7711861SMarek.Pospisil@Sun.COM
7811861SMarek.Pospisil@Sun.COM /* door IO buffer: */
7911861SMarek.Pospisil@Sun.COM kctx->auk_dbuffer =
8011861SMarek.Pospisil@Sun.COM kmem_alloc(AU_DBUF_HEADER + kctx->auk_queue.bufsz, KM_SLEEP);
8111861SMarek.Pospisil@Sun.COM
8211861SMarek.Pospisil@Sun.COM /* locks and cv's */
8311861SMarek.Pospisil@Sun.COM
8411861SMarek.Pospisil@Sun.COM mutex_init(&(kctx->auk_eagain_mutex), NULL, MUTEX_DEFAULT, NULL);
8511861SMarek.Pospisil@Sun.COM cv_init(&(kctx->auk_eagain_cv), NULL, CV_DRIVER, NULL);
8611861SMarek.Pospisil@Sun.COM
8711861SMarek.Pospisil@Sun.COM mutex_init(&(kctx->auk_svc_lock), NULL, MUTEX_DEFAULT, NULL);
8811861SMarek.Pospisil@Sun.COM
8911861SMarek.Pospisil@Sun.COM mutex_init(&(kctx->auk_queue.lock), NULL, MUTEX_DEFAULT, NULL);
9011861SMarek.Pospisil@Sun.COM cv_init(&(kctx->auk_queue.write_cv), NULL, CV_DRIVER, NULL);
9111861SMarek.Pospisil@Sun.COM cv_init(&(kctx->auk_queue.read_cv), NULL, CV_DRIVER, NULL);
9211861SMarek.Pospisil@Sun.COM
9311861SMarek.Pospisil@Sun.COM return (kctx);
9411861SMarek.Pospisil@Sun.COM }
9511861SMarek.Pospisil@Sun.COM
9611861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
9711861SMarek.Pospisil@Sun.COM static void
au_zone_shutdown(zoneid_t zone,void * arg)9811861SMarek.Pospisil@Sun.COM au_zone_shutdown(zoneid_t zone, void *arg)
9911861SMarek.Pospisil@Sun.COM {
10011861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = arg;
10111861SMarek.Pospisil@Sun.COM
10211861SMarek.Pospisil@Sun.COM if (audit_active == C2AUDIT_LOADED && (kctx->auk_zid == GLOBAL_ZONEID ||
10311861SMarek.Pospisil@Sun.COM (audit_policy | AUDIT_PERZONE)) && (kctx->auk_current_vp != NULL))
10411861SMarek.Pospisil@Sun.COM (void) au_doormsg(kctx, AU_DBUF_SHUTDOWN, NULL);
10511861SMarek.Pospisil@Sun.COM
10611861SMarek.Pospisil@Sun.COM kctx->auk_valid = AUK_INVALID;
10711861SMarek.Pospisil@Sun.COM
10811861SMarek.Pospisil@Sun.COM /* shutdown the output thread if it is still running */
10911861SMarek.Pospisil@Sun.COM kctx->auk_auditstate = AUC_NOAUDIT;
11011861SMarek.Pospisil@Sun.COM
11111861SMarek.Pospisil@Sun.COM if (kctx->auk_output_active) {
11211861SMarek.Pospisil@Sun.COM mutex_enter(&(kctx->auk_queue.lock));
11311861SMarek.Pospisil@Sun.COM cv_broadcast(&(kctx->auk_queue.read_cv));
11411861SMarek.Pospisil@Sun.COM mutex_exit(&(kctx->auk_queue.lock));
11511861SMarek.Pospisil@Sun.COM
11611861SMarek.Pospisil@Sun.COM taskq_destroy(kctx->auk_taskq);
11711861SMarek.Pospisil@Sun.COM }
11811861SMarek.Pospisil@Sun.COM }
11911861SMarek.Pospisil@Sun.COM
12011861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
12111861SMarek.Pospisil@Sun.COM static void
au_zone_destroy(zoneid_t zone,void * arg)12211861SMarek.Pospisil@Sun.COM au_zone_destroy(zoneid_t zone, void *arg)
12311861SMarek.Pospisil@Sun.COM {
12411861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = arg;
12511861SMarek.Pospisil@Sun.COM
12611861SMarek.Pospisil@Sun.COM ASSERT(kctx->auk_auditstate == AUC_NOAUDIT);
12711861SMarek.Pospisil@Sun.COM
12811861SMarek.Pospisil@Sun.COM mutex_destroy(&(kctx->auk_eagain_mutex));
12911861SMarek.Pospisil@Sun.COM cv_destroy(&(kctx->auk_eagain_cv));
13011861SMarek.Pospisil@Sun.COM
13111861SMarek.Pospisil@Sun.COM mutex_destroy(&(kctx->auk_svc_lock));
13211861SMarek.Pospisil@Sun.COM
13311861SMarek.Pospisil@Sun.COM mutex_enter(&(kctx->auk_queue.lock));
13411861SMarek.Pospisil@Sun.COM if (kctx->auk_queue.head != NULL) {
13511861SMarek.Pospisil@Sun.COM au_free_rec(kctx->auk_queue.head);
13611861SMarek.Pospisil@Sun.COM }
13711861SMarek.Pospisil@Sun.COM mutex_exit(&(kctx->auk_queue.lock));
13811861SMarek.Pospisil@Sun.COM
13911861SMarek.Pospisil@Sun.COM mutex_destroy(&(kctx->auk_queue.lock));
14011861SMarek.Pospisil@Sun.COM
14111861SMarek.Pospisil@Sun.COM cv_destroy(&(kctx->auk_queue.write_cv));
14211861SMarek.Pospisil@Sun.COM cv_destroy(&(kctx->auk_queue.read_cv));
14311861SMarek.Pospisil@Sun.COM
144*11965SMarek.Pospisil@Sun.COM kmem_free(kctx->auk_dbuffer, AU_DBUF_HEADER + kctx->auk_queue.buflen);
14511861SMarek.Pospisil@Sun.COM
14611861SMarek.Pospisil@Sun.COM kmem_free(kctx, sizeof (au_kcontext_t));
14711861SMarek.Pospisil@Sun.COM }
14811861SMarek.Pospisil@Sun.COM
14911861SMarek.Pospisil@Sun.COM void
au_zone_setup()15011861SMarek.Pospisil@Sun.COM au_zone_setup()
15111861SMarek.Pospisil@Sun.COM {
15211861SMarek.Pospisil@Sun.COM zone_key_create(&au_zone_key, au_zone_init, au_zone_shutdown,
15311861SMarek.Pospisil@Sun.COM au_zone_destroy);
15411861SMarek.Pospisil@Sun.COM
15511861SMarek.Pospisil@Sun.COM }
15611861SMarek.Pospisil@Sun.COM
15711861SMarek.Pospisil@Sun.COM int
au_zone_getstate(const au_kcontext_t * context)15811861SMarek.Pospisil@Sun.COM au_zone_getstate(const au_kcontext_t *context)
15911861SMarek.Pospisil@Sun.COM {
16011861SMarek.Pospisil@Sun.COM au_kcontext_t *tcontext;
16111861SMarek.Pospisil@Sun.COM
16211861SMarek.Pospisil@Sun.COM if (context != NULL)
16311861SMarek.Pospisil@Sun.COM return (context->auk_auditstate);
16411861SMarek.Pospisil@Sun.COM tcontext = GET_KCTX_PZ;
16511861SMarek.Pospisil@Sun.COM return (tcontext->auk_auditstate);
16611861SMarek.Pospisil@Sun.COM }
167