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