1*11861SMarek.Pospisil@Sun.COM /* 2*11861SMarek.Pospisil@Sun.COM * CDDL HEADER START 3*11861SMarek.Pospisil@Sun.COM * 4*11861SMarek.Pospisil@Sun.COM * The contents of this file are subject to the terms of the 5*11861SMarek.Pospisil@Sun.COM * Common Development and Distribution License (the "License"). 6*11861SMarek.Pospisil@Sun.COM * You may not use this file except in compliance with the License. 7*11861SMarek.Pospisil@Sun.COM * 8*11861SMarek.Pospisil@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*11861SMarek.Pospisil@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*11861SMarek.Pospisil@Sun.COM * See the License for the specific language governing permissions 11*11861SMarek.Pospisil@Sun.COM * and limitations under the License. 12*11861SMarek.Pospisil@Sun.COM * 13*11861SMarek.Pospisil@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*11861SMarek.Pospisil@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*11861SMarek.Pospisil@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*11861SMarek.Pospisil@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*11861SMarek.Pospisil@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*11861SMarek.Pospisil@Sun.COM * 19*11861SMarek.Pospisil@Sun.COM * CDDL HEADER END 20*11861SMarek.Pospisil@Sun.COM */ 21*11861SMarek.Pospisil@Sun.COM /* 22*11861SMarek.Pospisil@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23*11861SMarek.Pospisil@Sun.COM * Use is subject to license terms. 24*11861SMarek.Pospisil@Sun.COM */ 25*11861SMarek.Pospisil@Sun.COM 26*11861SMarek.Pospisil@Sun.COM 27*11861SMarek.Pospisil@Sun.COM #include <c2/audit.h> 28*11861SMarek.Pospisil@Sun.COM #include <c2/audit_kernel.h> 29*11861SMarek.Pospisil@Sun.COM #include <c2/audit_record.h> 30*11861SMarek.Pospisil@Sun.COM #include <sys/kmem.h> 31*11861SMarek.Pospisil@Sun.COM #include <sys/param.h> 32*11861SMarek.Pospisil@Sun.COM #include <sys/systm.h> 33*11861SMarek.Pospisil@Sun.COM #include <sys/taskq.h> 34*11861SMarek.Pospisil@Sun.COM #include <sys/t_lock.h> 35*11861SMarek.Pospisil@Sun.COM #include <sys/thread.h> 36*11861SMarek.Pospisil@Sun.COM #include <sys/types.h> 37*11861SMarek.Pospisil@Sun.COM #include <sys/zone.h> 38*11861SMarek.Pospisil@Sun.COM 39*11861SMarek.Pospisil@Sun.COM zone_key_t au_zone_key; 40*11861SMarek.Pospisil@Sun.COM 41*11861SMarek.Pospisil@Sun.COM /*ARGSUSED*/ 42*11861SMarek.Pospisil@Sun.COM static void * 43*11861SMarek.Pospisil@Sun.COM au_zone_init(zoneid_t zone) 44*11861SMarek.Pospisil@Sun.COM { 45*11861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = kmem_zalloc(sizeof (au_kcontext_t), KM_SLEEP); 46*11861SMarek.Pospisil@Sun.COM static au_kcontext_t *global_kctx = NULL; 47*11861SMarek.Pospisil@Sun.COM 48*11861SMarek.Pospisil@Sun.COM /* 49*11861SMarek.Pospisil@Sun.COM * INGLOBALZONE(curproc) is invalid at this point, so check for 50*11861SMarek.Pospisil@Sun.COM * zone 0 51*11861SMarek.Pospisil@Sun.COM */ 52*11861SMarek.Pospisil@Sun.COM 53*11861SMarek.Pospisil@Sun.COM if (zone == 0) { 54*11861SMarek.Pospisil@Sun.COM global_kctx = kctx; 55*11861SMarek.Pospisil@Sun.COM global_zone->zone_audit_kctxt = kctx; 56*11861SMarek.Pospisil@Sun.COM } else { 57*11861SMarek.Pospisil@Sun.COM kctx->auk_policy = global_kctx->auk_policy; 58*11861SMarek.Pospisil@Sun.COM curproc->p_zone->zone_audit_kctxt = kctx; 59*11861SMarek.Pospisil@Sun.COM } 60*11861SMarek.Pospisil@Sun.COM kctx->auk_valid = AUK_VALID; 61*11861SMarek.Pospisil@Sun.COM kctx->auk_zid = zone; 62*11861SMarek.Pospisil@Sun.COM 63*11861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_type = AU_IPv4; 64*11861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_auid = AU_NOAUDITID; 65*11861SMarek.Pospisil@Sun.COM kctx->auk_auditstate = AUC_INIT_AUDIT; 66*11861SMarek.Pospisil@Sun.COM 67*11861SMarek.Pospisil@Sun.COM /* setup defaults for audit queue flow control */ 68*11861SMarek.Pospisil@Sun.COM kctx->auk_queue.hiwater = AQ_HIWATER; 69*11861SMarek.Pospisil@Sun.COM kctx->auk_queue.lowater = AQ_LOWATER; 70*11861SMarek.Pospisil@Sun.COM kctx->auk_queue.bufsz = AQ_BUFSZ; 71*11861SMarek.Pospisil@Sun.COM kctx->auk_queue.buflen = AQ_BUFSZ; 72*11861SMarek.Pospisil@Sun.COM kctx->auk_queue.delay = AQ_DELAY; 73*11861SMarek.Pospisil@Sun.COM 74*11861SMarek.Pospisil@Sun.COM /* statistics per zone */ 75*11861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_version = TOKEN_VERSION; 76*11861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_numevent = MAX_KEVENTS; 77*11861SMarek.Pospisil@Sun.COM 78*11861SMarek.Pospisil@Sun.COM /* door IO buffer: */ 79*11861SMarek.Pospisil@Sun.COM kctx->auk_dbuffer = 80*11861SMarek.Pospisil@Sun.COM kmem_alloc(AU_DBUF_HEADER + kctx->auk_queue.bufsz, KM_SLEEP); 81*11861SMarek.Pospisil@Sun.COM 82*11861SMarek.Pospisil@Sun.COM /* locks and cv's */ 83*11861SMarek.Pospisil@Sun.COM 84*11861SMarek.Pospisil@Sun.COM mutex_init(&(kctx->auk_eagain_mutex), NULL, MUTEX_DEFAULT, NULL); 85*11861SMarek.Pospisil@Sun.COM cv_init(&(kctx->auk_eagain_cv), NULL, CV_DRIVER, NULL); 86*11861SMarek.Pospisil@Sun.COM 87*11861SMarek.Pospisil@Sun.COM mutex_init(&(kctx->auk_svc_lock), NULL, MUTEX_DEFAULT, NULL); 88*11861SMarek.Pospisil@Sun.COM 89*11861SMarek.Pospisil@Sun.COM mutex_init(&(kctx->auk_queue.lock), NULL, MUTEX_DEFAULT, NULL); 90*11861SMarek.Pospisil@Sun.COM cv_init(&(kctx->auk_queue.write_cv), NULL, CV_DRIVER, NULL); 91*11861SMarek.Pospisil@Sun.COM cv_init(&(kctx->auk_queue.read_cv), NULL, CV_DRIVER, NULL); 92*11861SMarek.Pospisil@Sun.COM 93*11861SMarek.Pospisil@Sun.COM return (kctx); 94*11861SMarek.Pospisil@Sun.COM } 95*11861SMarek.Pospisil@Sun.COM 96*11861SMarek.Pospisil@Sun.COM /*ARGSUSED*/ 97*11861SMarek.Pospisil@Sun.COM static void 98*11861SMarek.Pospisil@Sun.COM au_zone_shutdown(zoneid_t zone, void *arg) 99*11861SMarek.Pospisil@Sun.COM { 100*11861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = arg; 101*11861SMarek.Pospisil@Sun.COM 102*11861SMarek.Pospisil@Sun.COM if (audit_active == C2AUDIT_LOADED && (kctx->auk_zid == GLOBAL_ZONEID || 103*11861SMarek.Pospisil@Sun.COM (audit_policy | AUDIT_PERZONE)) && (kctx->auk_current_vp != NULL)) 104*11861SMarek.Pospisil@Sun.COM (void) au_doormsg(kctx, AU_DBUF_SHUTDOWN, NULL); 105*11861SMarek.Pospisil@Sun.COM 106*11861SMarek.Pospisil@Sun.COM kctx->auk_valid = AUK_INVALID; 107*11861SMarek.Pospisil@Sun.COM 108*11861SMarek.Pospisil@Sun.COM /* shutdown the output thread if it is still running */ 109*11861SMarek.Pospisil@Sun.COM kctx->auk_auditstate = AUC_NOAUDIT; 110*11861SMarek.Pospisil@Sun.COM 111*11861SMarek.Pospisil@Sun.COM if (kctx->auk_output_active) { 112*11861SMarek.Pospisil@Sun.COM mutex_enter(&(kctx->auk_queue.lock)); 113*11861SMarek.Pospisil@Sun.COM cv_broadcast(&(kctx->auk_queue.read_cv)); 114*11861SMarek.Pospisil@Sun.COM mutex_exit(&(kctx->auk_queue.lock)); 115*11861SMarek.Pospisil@Sun.COM 116*11861SMarek.Pospisil@Sun.COM taskq_destroy(kctx->auk_taskq); 117*11861SMarek.Pospisil@Sun.COM } 118*11861SMarek.Pospisil@Sun.COM } 119*11861SMarek.Pospisil@Sun.COM 120*11861SMarek.Pospisil@Sun.COM /*ARGSUSED*/ 121*11861SMarek.Pospisil@Sun.COM static void 122*11861SMarek.Pospisil@Sun.COM au_zone_destroy(zoneid_t zone, void *arg) 123*11861SMarek.Pospisil@Sun.COM { 124*11861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = arg; 125*11861SMarek.Pospisil@Sun.COM 126*11861SMarek.Pospisil@Sun.COM ASSERT(kctx->auk_auditstate == AUC_NOAUDIT); 127*11861SMarek.Pospisil@Sun.COM 128*11861SMarek.Pospisil@Sun.COM mutex_destroy(&(kctx->auk_eagain_mutex)); 129*11861SMarek.Pospisil@Sun.COM cv_destroy(&(kctx->auk_eagain_cv)); 130*11861SMarek.Pospisil@Sun.COM 131*11861SMarek.Pospisil@Sun.COM mutex_destroy(&(kctx->auk_svc_lock)); 132*11861SMarek.Pospisil@Sun.COM 133*11861SMarek.Pospisil@Sun.COM mutex_enter(&(kctx->auk_queue.lock)); 134*11861SMarek.Pospisil@Sun.COM if (kctx->auk_queue.head != NULL) { 135*11861SMarek.Pospisil@Sun.COM au_free_rec(kctx->auk_queue.head); 136*11861SMarek.Pospisil@Sun.COM } 137*11861SMarek.Pospisil@Sun.COM mutex_exit(&(kctx->auk_queue.lock)); 138*11861SMarek.Pospisil@Sun.COM 139*11861SMarek.Pospisil@Sun.COM mutex_destroy(&(kctx->auk_queue.lock)); 140*11861SMarek.Pospisil@Sun.COM 141*11861SMarek.Pospisil@Sun.COM cv_destroy(&(kctx->auk_queue.write_cv)); 142*11861SMarek.Pospisil@Sun.COM cv_destroy(&(kctx->auk_queue.read_cv)); 143*11861SMarek.Pospisil@Sun.COM 144*11861SMarek.Pospisil@Sun.COM kmem_free(kctx->auk_dbuffer, AU_DBUF_HEADER + kctx->auk_queue.bufsz); 145*11861SMarek.Pospisil@Sun.COM 146*11861SMarek.Pospisil@Sun.COM kmem_free(kctx, sizeof (au_kcontext_t)); 147*11861SMarek.Pospisil@Sun.COM } 148*11861SMarek.Pospisil@Sun.COM 149*11861SMarek.Pospisil@Sun.COM void 150*11861SMarek.Pospisil@Sun.COM au_zone_setup() 151*11861SMarek.Pospisil@Sun.COM { 152*11861SMarek.Pospisil@Sun.COM zone_key_create(&au_zone_key, au_zone_init, au_zone_shutdown, 153*11861SMarek.Pospisil@Sun.COM au_zone_destroy); 154*11861SMarek.Pospisil@Sun.COM 155*11861SMarek.Pospisil@Sun.COM } 156*11861SMarek.Pospisil@Sun.COM 157*11861SMarek.Pospisil@Sun.COM int 158*11861SMarek.Pospisil@Sun.COM au_zone_getstate(const au_kcontext_t *context) 159*11861SMarek.Pospisil@Sun.COM { 160*11861SMarek.Pospisil@Sun.COM au_kcontext_t *tcontext; 161*11861SMarek.Pospisil@Sun.COM 162*11861SMarek.Pospisil@Sun.COM if (context != NULL) 163*11861SMarek.Pospisil@Sun.COM return (context->auk_auditstate); 164*11861SMarek.Pospisil@Sun.COM tcontext = GET_KCTX_PZ; 165*11861SMarek.Pospisil@Sun.COM return (tcontext->auk_auditstate); 166*11861SMarek.Pospisil@Sun.COM } 167