1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * au_preselect.c 29 */ 30 31 #include <sys/types.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <bsm/audit.h> 35 #include <bsm/libbsm.h> 36 #include <synch.h> 37 38 #define ALLOC_INIT (600) /* initially allocate ALLOC_INIT map entries */ 39 #define ALLOC_INCR (100) /* if more map entries are needed, realloc */ 40 /* in ALLOC_INCR increments */ 41 42 static int alloc_map(); 43 static int load_map(); 44 static int realloc_map(); 45 46 typedef struct event_map { 47 au_event_t event; /* audit event number */ 48 au_class_t class; /* audit event class mask */ 49 } event_map_t; 50 51 static event_map_t *event_map; /* the map */ 52 static uint_t alloc_count; /* number of entries currently allocated */ 53 static uint_t event_count; /* number of entries in map */ 54 static mutex_t mutex_au_preselect = DEFAULTMUTEX; 55 56 /* 57 * au_preselect: 58 * 59 * Keep a dynamic array of event<-->class mappings. 60 * Refresh the map when the value of flag is AU_PRS_REREAD. 61 * Return: 62 * 1: The event is preselected. 63 * 0: The event is not preselected. 64 * -1: There was an error: 65 * Couldn't allocate memory. 66 * Couldn't find event. 67 */ 68 int 69 au_preselect(au_event_t au_event, au_mask_t *au_mask_p, int sorf, int flag) 70 { 71 static char been_here_before; /* we cache the map */ 72 register int i; 73 register au_class_t comp_class; 74 75 (void) mutex_lock(&mutex_au_preselect); 76 if (!been_here_before) { 77 if (alloc_map() == -1) { 78 (void) mutex_unlock(&mutex_au_preselect); 79 return (-1); 80 } 81 82 if (load_map() == -1) { 83 (void) mutex_unlock(&mutex_au_preselect); 84 return (-1); 85 } 86 87 been_here_before = 1; 88 } 89 90 /* 91 * Don't use the cache. Re-read the audit_event(5) db every time 92 */ 93 if (flag == AU_PRS_REREAD) { 94 if (load_map() == -1) { 95 (void) mutex_unlock(&mutex_au_preselect); 96 return (-1); 97 } 98 } 99 100 /* Determine what portion of the preselection mask to check. */ 101 if (sorf == AU_PRS_SUCCESS) 102 comp_class = au_mask_p->am_success; 103 else if (sorf == AU_PRS_FAILURE) 104 comp_class = au_mask_p->am_failure; 105 else 106 comp_class = au_mask_p->am_success | au_mask_p->am_failure; 107 108 for (i = 0; i < event_count; i++) { 109 if (event_map[i].event == au_event) { 110 if (event_map[i].class & comp_class) { 111 (void) mutex_unlock(&mutex_au_preselect); 112 return (1); 113 } else { 114 (void) mutex_unlock(&mutex_au_preselect); 115 return (0); 116 } 117 } 118 } 119 120 (void) mutex_unlock(&mutex_au_preselect); 121 return (-1); /* could not find event in the table */ 122 } 123 124 /* 125 * Initially allocate about as many map entries as are there 126 * are audit events shipped with the system. For sites 127 * that don't add audit events, this should be enough. 128 */ 129 static int 130 alloc_map() 131 { 132 if ((event_map = (event_map_t *) 133 calloc(ALLOC_INIT, (size_t)sizeof (event_map_t))) == 134 (event_map_t *)NULL) 135 return (-1); 136 else 137 alloc_count = ALLOC_INIT; 138 139 return (0); 140 } 141 142 /* 143 * load the event<->class map into memory 144 */ 145 static int 146 load_map() 147 { 148 register au_event_ent_t *evp; 149 150 event_count = 0; 151 setauevent(); 152 while ((evp = getauevent()) != (au_event_ent_t *)NULL) { 153 if (event_count > alloc_count) 154 if (realloc_map() == -1) { 155 endauevent(); 156 return (-1); 157 } 158 event_map[event_count].event = evp->ae_number; 159 event_map[event_count].class = evp->ae_class; 160 ++event_count; 161 } 162 endauevent(); 163 164 return (0); 165 } 166 167 /* 168 * realloc the event map in ALLOC_INCR increments 169 */ 170 static int 171 realloc_map() 172 { 173 register size_t rsize; 174 rsize = sizeof (event_map_t) * (alloc_count + ALLOC_INCR); 175 176 if ((event_map = (event_map_t *) 177 realloc(event_map, rsize)) == (event_map_t *)NULL) 178 return (-1); 179 180 return (0); 181 } 182