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