Home | History | Annotate | Download | only in c2
      1  0  stevel /*
      2  0  stevel  * CDDL HEADER START
      3  0  stevel  *
      4  0  stevel  * The contents of this file are subject to the terms of the
      5  0  stevel  * Common Development and Distribution License, Version 1.0 only
      6  0  stevel  * (the "License").  You may not use this file except in compliance
      7  0  stevel  * with the License.
      8  0  stevel  *
      9  0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  0  stevel  * or http://www.opensolaris.org/os/licensing.
     11  0  stevel  * See the License for the specific language governing permissions
     12  0  stevel  * and limitations under the License.
     13  0  stevel  *
     14  0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     15  0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     17  0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     18  0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  0  stevel  *
     20  0  stevel  * CDDL HEADER END
     21  0  stevel  */
     22  0  stevel /*
     23  0  stevel  * Copyright 1991-2003 Sun Microsystems, Inc.  All rights reserved.
     24  0  stevel  * Use is subject to license terms.
     25  0  stevel  */
     26  0  stevel 
     27  0  stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28  0  stevel 
     29  0  stevel /*
     30  0  stevel  * @(#)audit_path.c 2.7 92/02/16 SMI; SunOS CMW
     31  0  stevel  * @(#)audit_path.c 4.2.1.2 91/05/08 SMI; BSM Module
     32  0  stevel  *
     33  0  stevel  * This code does the audit path processes. Part of this is still in
     34  0  stevel  * audit.c and will be moved here when time permits.
     35  0  stevel  *
     36  0  stevel  * Note that audit debuging is enabled here. We will turn it off at
     37  0  stevel  * beta shipment.
     38  0  stevel  */
     39  0  stevel 
     40  0  stevel #include <sys/types.h>
     41  0  stevel #include <sys/param.h>
     42  0  stevel #include <sys/systm.h>
     43  0  stevel #include <sys/user.h>
     44  0  stevel #include <sys/vnode.h>
     45  0  stevel #include <sys/vfs.h>
     46  0  stevel #include <sys/kmem.h>		/* for KM_SLEEP */
     47  0  stevel #include <sys/proc.h>
     48  0  stevel #include <sys/uio.h>
     49  0  stevel #include <sys/file.h>
     50  0  stevel #include <sys/stat.h>
     51  0  stevel #include <sys/pathname.h>
     52  0  stevel #include <sys/acct.h>
     53  0  stevel #include <c2/audit.h>
     54  0  stevel #include <c2/audit_kernel.h>
     55  0  stevel #include <c2/audit_record.h>
     56  0  stevel #include <sys/sysmacros.h>
     57  0  stevel #include <sys/atomic.h>
     58  0  stevel 
     59  0  stevel /*
     60  0  stevel  * allocate a new auditpath
     61  0  stevel  *	newsect = increment sections count,
     62  0  stevel  *	charincr = change in strings storage
     63  0  stevel  */
     64  0  stevel struct audit_path *
     65  0  stevel au_pathdup(const struct audit_path *oldapp, int newsect, int charincr)
     66  0  stevel {
     67  0  stevel 	struct audit_path	*newapp;
     68  0  stevel 	int	i, alloc_size, oldlen;
     69  0  stevel 	char	*oldcp, *newcp;
     70  0  stevel 
     71  0  stevel 	newsect = (newsect != 0);
     72  0  stevel 	oldcp = oldapp->audp_sect[0];
     73  0  stevel 	oldlen = (oldapp->audp_sect[oldapp->audp_cnt] - oldcp);
     74  0  stevel 	alloc_size = sizeof (struct audit_path) +
     75  0  stevel 	    (oldapp->audp_cnt + newsect) * sizeof (char *) +
     76  0  stevel 	    oldlen + charincr;
     77  0  stevel 
     78  0  stevel 	newapp = kmem_alloc(alloc_size, KM_SLEEP);
     79  0  stevel 	newapp->audp_ref = 1;
     80  0  stevel 	newapp->audp_size = alloc_size;
     81  0  stevel 
     82  0  stevel 	newapp->audp_cnt = oldapp->audp_cnt + newsect;
     83  0  stevel 	newcp = (char *)(&newapp->audp_sect[newapp->audp_cnt + 1]);
     84  0  stevel 	for (i = 0; i <= oldapp->audp_cnt; i++) {
     85  0  stevel 		newapp->audp_sect[i] = newcp +
     86  0  stevel 		    (oldapp->audp_sect[i] - oldcp);
     87  0  stevel 	}
     88  0  stevel 	/*
     89  0  stevel 	 * if this is a new section, set its end
     90  0  stevel 	 * if this is an extended section, reset its end
     91  0  stevel 	 */
     92  0  stevel 	newapp->audp_sect[newapp->audp_cnt] = newcp + oldlen + charincr;
     93  0  stevel 	/* copy all of the old strings */
     94  0  stevel 	bcopy(oldcp, newcp, oldlen);
     95  0  stevel 
     96  0  stevel 	return (newapp);
     97  0  stevel }
     98  0  stevel 
     99  0  stevel /*
    100  0  stevel  * increment audit path reference count
    101  0  stevel  */
    102  0  stevel void
    103  0  stevel au_pathhold(struct audit_path *app)
    104  0  stevel {
    105  0  stevel 	atomic_add_32(&app->audp_ref, 1);
    106  0  stevel }
    107  0  stevel 
    108  0  stevel /*
    109  0  stevel  * decrement audit path reference count
    110  0  stevel  */
    111  0  stevel void
    112  0  stevel au_pathrele(struct audit_path *app)
    113  0  stevel {
    114  0  stevel 	if (atomic_add_32_nv(&app->audp_ref, -1) > 0)
    115  0  stevel 		return;
    116  0  stevel 	kmem_free(app, app->audp_size);
    117  0  stevel }
    118  0  stevel 
    119  0  stevel 
    120  0  stevel int
    121  0  stevel au_token_size(m)
    122  0  stevel 	token_t *m;
    123  0  stevel {
    124  0  stevel 	int i;
    125  0  stevel 
    126  0  stevel 	if (m == (token_t *)0)
    127  0  stevel 		return (0);
    128  0  stevel 
    129  0  stevel 	for (i = 0; m != (token_t *)0; m = m->next_buf)
    130  0  stevel 		i += m->len;
    131  0  stevel 	return (i);
    132  0  stevel }
    133  0  stevel 
    134  0  stevel token_t *
    135  0  stevel au_set(cp, size)
    136  0  stevel 	caddr_t  cp;
    137  0  stevel 	uint_t    size;
    138  0  stevel {
    139  0  stevel 	au_buff_t *head;
    140  0  stevel 	au_buff_t *tail;
    141  0  stevel 	au_buff_t *m;
    142  0  stevel 	uint_t	l;
    143  0  stevel 
    144  0  stevel 	head = NULL;
    145  0  stevel 	tail = NULL;	/* only to satisfy lint */
    146  0  stevel 
    147  0  stevel 	while (size) {
    148  0  stevel 		m = au_get_buff();
    149  0  stevel 		l = MIN(size, AU_BUFSIZE);
    150  0  stevel 		bcopy(cp, memtod(m, char *), l);
    151  0  stevel 		m->len = l;
    152  0  stevel 
    153  0  stevel 		if (head)
    154  0  stevel 			tail->next_buf = m;	/* tail set if head set */
    155  0  stevel 		else
    156  0  stevel 			head = m;
    157  0  stevel 		tail = m;
    158  0  stevel 		size -= l;
    159  0  stevel 		cp += l;
    160  0  stevel 	}
    161  0  stevel 
    162  0  stevel 	return (head);
    163  0  stevel }
    164  0  stevel 
    165  0  stevel token_t *
    166  0  stevel au_append_token(chain, m)
    167  0  stevel 	token_t *chain;
    168  0  stevel 	token_t *m;
    169  0  stevel {
    170  0  stevel 	token_t *mbp;
    171  0  stevel 
    172  0  stevel 	if (chain == (token_t *)0)
    173  0  stevel 		return (m);
    174  0  stevel 
    175  0  stevel 	if (m == (token_t *)0)
    176  0  stevel 		return (chain);
    177  0  stevel 
    178  0  stevel 	for (mbp = chain; mbp->next_buf != (token_t *)0; mbp = mbp->next_buf)
    179  0  stevel 		;
    180  0  stevel 	mbp->next_buf = m;
    181  0  stevel 	return (chain);
    182  0  stevel }
    183  0  stevel 
    184  0  stevel 
    185  0  stevel void
    186  0  stevel audit_fixpath(struct audit_path *app, int len)
    187  0  stevel {
    188  0  stevel 	int id;		/* index of where we are in destination string */
    189  0  stevel 	int is;		/* index of where we are in source string */
    190  0  stevel 	int cnt;	/* # of levels in audit_path */
    191  0  stevel 	int slashseen;	/* have we seen a slash */
    192  0  stevel 	char *s;	/* start of top-level string */
    193  0  stevel 	char c;
    194  0  stevel 
    195  0  stevel 	cnt = app->audp_cnt;
    196  0  stevel 	s = app->audp_sect[cnt - 1];
    197  0  stevel 	is = (app->audp_sect[cnt] - s) - len;
    198  0  stevel 	if (is <= 2)
    199  0  stevel 		is = 0;	/* catch leading // or ./ */
    200  0  stevel 	slashseen = (is > 0);
    201  0  stevel 	for (id = is; ; is++) {
    202  0  stevel 		if ((c = s[is]) == '\0') {
    203  0  stevel 			/* that's all folks, we've reached the end of input */
    204  0  stevel 			if (id > 1 && s[id-1] == '/') {
    205  0  stevel 				/* remove terminating / */
    206  0  stevel 				--id;
    207  0  stevel 			}
    208  0  stevel 			s[id++] = '\0';
    209  0  stevel 			break;
    210  0  stevel 		}
    211  0  stevel 		if (slashseen) {
    212  0  stevel 			/* previous character was a / */
    213  0  stevel 			if (c == '/') {
    214  0  stevel 				/* another slash, ignore it */
    215  0  stevel 				continue;
    216  0  stevel 			}
    217  0  stevel 		} else if (c == '/') {
    218  0  stevel 			/* we see a /, just copy it and try again */
    219  0  stevel 			slashseen = 1;
    220  0  stevel 			s[id++] = c;
    221  0  stevel 			continue;
    222  0  stevel 		}
    223  0  stevel 		if (c == '.') {
    224  0  stevel 			if ((c = s[is+1]) == '\0') {
    225  0  stevel 				/* XXX/. seen */
    226  0  stevel 				if (id > 1)
    227  0  stevel 					id--;
    228  0  stevel 				continue;
    229  0  stevel 			}
    230  0  stevel 			if (c == '/') {
    231  0  stevel 				/* XXX/./ seen */
    232  0  stevel 				is += 1;
    233  0  stevel 				continue;
    234  0  stevel 			}
    235  0  stevel 			if (c == '.' && (s[is+2] == '\0' || s[is+2] == '/')) {
    236  0  stevel 				/* XXX/.. or XXX/../ seen */
    237  0  stevel 				is++;
    238  0  stevel 				if (id == 0 && cnt > 1) {
    239  0  stevel 					char	*s_attr;
    240  0  stevel 					/* .. refers to attributed object */
    241  0  stevel 					app->audp_cnt = --cnt;
    242  0  stevel 					s_attr = s;
    243  0  stevel 					s = app->audp_sect[cnt - 1];
    244  0  stevel 					id = s_attr - s;
    245  0  stevel 					is += id;
    246  0  stevel 					id--;
    247  0  stevel 					slashseen = 0;
    248  0  stevel 					continue;
    249  0  stevel 				}
    250  0  stevel 				/* backup over previous component */
    251  0  stevel 				if (id > 0)
    252  0  stevel 					id--;
    253  0  stevel 				while (id > 0 && s[id - 1] != '/')
    254  0  stevel 					id--;
    255  0  stevel 				continue;
    256  0  stevel 			}
    257  0  stevel 		}
    258  0  stevel 		/* copy component name and terminating /, if any */
    259  0  stevel 		for (;;) {
    260  0  stevel 			c = s[is++];
    261  0  stevel 			if (c == '\0' || c == '/')
    262  0  stevel 				break;
    263  0  stevel 			s[id++] = c;
    264  0  stevel 		}
    265  0  stevel 		/* back up to before terminating '\0' or / */
    266  0  stevel 		slashseen = 0;
    267  0  stevel 		is -= 2;
    268  0  stevel 	}
    269  0  stevel 	/* fill empty attribute directory reference */
    270  0  stevel 	if (id == 1 && cnt > 1) {
    271  0  stevel 		s[0] = '.';
    272  0  stevel 		s[1] = '\0';
    273  0  stevel 		id = 2;
    274  0  stevel 	}
    275  0  stevel 	/* correct end pointer */
    276  0  stevel 	app->audp_sect[cnt] = s + id;
    277  0  stevel }
    278