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
au_token_size(m)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 *
au_set(cp,size)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 *
au_append_token(chain,m)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
audit_fixpath(struct audit_path * app,int len)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