Home | History | Annotate | Download | only in auditd
      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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <pthread.h>
     27 #include <memory.h>
     28 #include "queue.h"
     29 #include <stdio.h>
     30 #include <assert.h>
     31 #include "plugin.h"
     32 
     33 #define	DEBUG	0
     34 
     35 #if DEBUG
     36 extern FILE *dbfp;
     37 extern FILE *__auditd_debug_file_open();
     38 #define	DPRINT(x) {(void) fprintf x; }
     39 #else
     40 #define	DPRINT(x)
     41 #endif
     42 
     43 void
     44 audit_queue_init(au_queue_t *q)
     45 {
     46 	q->auq_head = NULL;
     47 	q->auq_tail = NULL;
     48 	(void) pthread_mutex_init(&q->auq_lock, NULL);
     49 	q->auq_count = 0;
     50 #if DEBUG
     51 	if (dbfp == NULL) {
     52 		dbfp = __auditd_debug_file_open();
     53 	}
     54 #endif
     55 }
     56 
     57 /*
     58  * enqueue()	caller creates queue entry
     59  */
     60 
     61 void
     62 audit_enqueue(au_queue_t *q,  void *p)
     63 {
     64 	(void) pthread_mutex_lock(&q->auq_lock);
     65 
     66 	DPRINT((dbfp, "enqueue0(%X): p=%X, head=%X, tail=%X, count=%d\n",
     67 	    q, p, q->auq_head, q->auq_tail, q->auq_count));
     68 
     69 	if (q->auq_head == NULL)
     70 		q->auq_head = p;
     71 	else {
     72 		DPRINT((dbfp, "\tindirect tail=%X\n",
     73 		    &(((audit_link_t *)(q->auq_tail))->aln_next)));
     74 
     75 		((audit_link_t *)(q->auq_tail))->aln_next = p;
     76 	}
     77 	q->auq_tail = p;
     78 	((audit_link_t *)p)->aln_next = NULL;
     79 	q->auq_count++;
     80 
     81 	DPRINT((dbfp, "enqueue1(%X): p=%X, head=%X, tail=%X, "
     82 	    "count=%d, pnext=%X\n",
     83 	    q, p, q->auq_head, q->auq_tail, q->auq_count,
     84 	    ((audit_link_t *)p)->aln_next));
     85 
     86 	(void) pthread_mutex_unlock(&q->auq_lock);
     87 }
     88 
     89 /*
     90  * audit_dequeue() returns entry; caller is responsible for free
     91  */
     92 
     93 int
     94 audit_dequeue(au_queue_t *q, void **p)
     95 {
     96 	(void) pthread_mutex_lock(&q->auq_lock);
     97 
     98 	if ((*p = q->auq_head) == NULL) {
     99 		DPRINT((dbfp, "dequeue1(%X): p=%X, head=%X, "
    100 		    "tail=%X, count=%d\n",
    101 		    q, *p, q->auq_head, q->auq_tail, q->auq_count));
    102 
    103 		(void) pthread_mutex_unlock(&q->auq_lock);
    104 		return (1);
    105 	}
    106 	q->auq_count--;
    107 
    108 	/* if *p is the last, next is NULL */
    109 	q->auq_head = ((audit_link_t *)*p)->aln_next;
    110 
    111 	DPRINT((dbfp, "dequeue0(%X): p=%X, head=%X, tail=%X, "
    112 	    "count=%d, pnext=%X\n",
    113 	    q, *p, q->auq_head, q->auq_tail, q->auq_count,
    114 	    ((audit_link_t *)*p)->aln_next));
    115 
    116 	(void) pthread_mutex_unlock(&q->auq_lock);
    117 	return (0);
    118 }
    119 
    120 /*
    121  * increment ref count
    122  */
    123 void
    124 audit_incr_ref(pthread_mutex_t *l, audit_rec_t *p)
    125 {
    126 	(void) pthread_mutex_lock(l);
    127 	p->abq_ref_count++;
    128 	DPRINT((dbfp, "incr_ref: p=%X, count=%d\n",
    129 	    p, p->abq_ref_count));
    130 	(void) pthread_mutex_unlock(l);
    131 }
    132 /*
    133  * decrement reference count; if it reaches zero,
    134  * return a pointer to it.  Otherwise, return NULL.
    135  */
    136 audit_rec_t *
    137 audit_release(pthread_mutex_t *l, audit_rec_t *p)
    138 {
    139 	assert(p != NULL);
    140 
    141 	(void) pthread_mutex_lock(l);
    142 
    143 	DPRINT((dbfp, "release: p=%X, count=%d\n",
    144 	    p, p->abq_ref_count));
    145 
    146 	if (--(p->abq_ref_count) > 0) {
    147 		(void) pthread_mutex_unlock(l);
    148 		return (NULL);
    149 	}
    150 	(void) pthread_mutex_unlock(l);
    151 
    152 	return (p);
    153 }
    154 
    155 int
    156 audit_queue_size(au_queue_t *q)
    157 {
    158 	int	size;
    159 
    160 	(void) pthread_mutex_lock(&q->auq_lock);
    161 	size = q->auq_count;
    162 	(void) pthread_mutex_unlock(&q->auq_lock);
    163 
    164 	return (size);
    165 }
    166 
    167 
    168 void
    169 audit_queue_destroy(au_queue_t *q)
    170 {
    171 	(void) pthread_mutex_destroy(&q->auq_lock);
    172 }
    173