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