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