Home | History | Annotate | Download | only in common
      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