xref: /illumos-gate/usr/src/uts/common/c2/audit_path.c (revision f3041bfa)
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 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * @(#)audit_path.c 2.7 92/02/16 SMI; SunOS CMW
28  * @(#)audit_path.c 4.2.1.2 91/05/08 SMI; BSM Module
29  *
30  * This code does the audit path processes. Part of this is still in
31  * audit.c and will be moved here when time permits.
32  *
33  * Note that audit debuging is enabled here. We will turn it off at
34  * beta shipment.
35  */
36 
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/user.h>
41 #include <sys/vnode.h>
42 #include <sys/vfs.h>
43 #include <sys/kmem.h>		/* for KM_SLEEP */
44 #include <sys/proc.h>
45 #include <sys/uio.h>
46 #include <sys/file.h>
47 #include <sys/stat.h>
48 #include <sys/pathname.h>
49 #include <sys/acct.h>
50 #include <c2/audit.h>
51 #include <c2/audit_kernel.h>
52 #include <c2/audit_record.h>
53 #include <sys/sysmacros.h>
54 #include <sys/atomic.h>
55 
56 
57 int
58 au_token_size(m)
59 	token_t *m;
60 {
61 	int i;
62 
63 	if (m == (token_t *)0)
64 		return (0);
65 
66 	for (i = 0; m != (token_t *)0; m = m->next_buf)
67 		i += m->len;
68 	return (i);
69 }
70 
71 token_t *
72 au_set(cp, size)
73 	caddr_t  cp;
74 	uint_t    size;
75 {
76 	au_buff_t *head;
77 	au_buff_t *tail;
78 	au_buff_t *m;
79 	uint_t	l;
80 
81 	head = NULL;
82 	tail = NULL;	/* only to satisfy lint */
83 
84 	while (size) {
85 		m = au_get_buff();
86 		l = MIN(size, AU_BUFSIZE);
87 		bcopy(cp, memtod(m, char *), l);
88 		m->len = l;
89 
90 		if (head)
91 			tail->next_buf = m;	/* tail set if head set */
92 		else
93 			head = m;
94 		tail = m;
95 		size -= l;
96 		cp += l;
97 	}
98 
99 	return (head);
100 }
101 
102 token_t *
103 au_append_token(chain, m)
104 	token_t *chain;
105 	token_t *m;
106 {
107 	token_t *mbp;
108 
109 	if (chain == (token_t *)0)
110 		return (m);
111 
112 	if (m == (token_t *)0)
113 		return (chain);
114 
115 	for (mbp = chain; mbp->next_buf != (token_t *)0; mbp = mbp->next_buf)
116 		;
117 	mbp->next_buf = m;
118 	return (chain);
119 }
120 
121 
122 void
123 audit_fixpath(struct audit_path *app, int len)
124 {
125 	int id;		/* index of where we are in destination string */
126 	int is;		/* index of where we are in source string */
127 	int cnt;	/* # of levels in audit_path */
128 	int slashseen;	/* have we seen a slash */
129 	char *s;	/* start of top-level string */
130 	char c;
131 
132 	cnt = app->audp_cnt;
133 	s = app->audp_sect[cnt - 1];
134 	is = (app->audp_sect[cnt] - s) - len;
135 	if (is <= 2)
136 		is = 0;	/* catch leading // or ./ */
137 	slashseen = (is > 0);
138 	for (id = is; ; is++) {
139 		if ((c = s[is]) == '\0') {
140 			/* that's all folks, we've reached the end of input */
141 			if (id > 1 && s[id-1] == '/') {
142 				/* remove terminating / */
143 				--id;
144 			}
145 			s[id++] = '\0';
146 			break;
147 		}
148 		if (slashseen) {
149 			/* previous character was a / */
150 			if (c == '/') {
151 				/* another slash, ignore it */
152 				continue;
153 			}
154 		} else if (c == '/') {
155 			/* we see a /, just copy it and try again */
156 			slashseen = 1;
157 			s[id++] = c;
158 			continue;
159 		}
160 		if (c == '.') {
161 			if ((c = s[is+1]) == '\0') {
162 				/* XXX/. seen */
163 				if (id > 1)
164 					id--;
165 				continue;
166 			}
167 			if (c == '/') {
168 				/* XXX/./ seen */
169 				is += 1;
170 				continue;
171 			}
172 			if (c == '.' && (s[is+2] == '\0' || s[is+2] == '/')) {
173 				/* XXX/.. or XXX/../ seen */
174 				is++;
175 				if (id == 0 && cnt > 1) {
176 					char	*s_attr;
177 					/* .. refers to attributed object */
178 					app->audp_cnt = --cnt;
179 					s_attr = s;
180 					s = app->audp_sect[cnt - 1];
181 					id = s_attr - s;
182 					is += id;
183 					id--;
184 					slashseen = 0;
185 					continue;
186 				}
187 				/* backup over previous component */
188 				if (id > 0)
189 					id--;
190 				while (id > 0 && s[id - 1] != '/')
191 					id--;
192 				continue;
193 			}
194 		}
195 		/* copy component name and terminating /, if any */
196 		for (;;) {
197 			c = s[is++];
198 			if (c == '\0' || c == '/')
199 				break;
200 			s[id++] = c;
201 		}
202 		/* back up to before terminating '\0' or / */
203 		slashseen = 0;
204 		is -= 2;
205 	}
206 	/* fill empty attribute directory reference */
207 	if (id == 1 && cnt > 1) {
208 		s[0] = '.';
209 		s[1] = '\0';
210 		id = 2;
211 	}
212 	/* correct end pointer */
213 	app->audp_sect[cnt] = s + id;
214 }
215