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