17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*005d3febSMarek Pospisil * Common Development and Distribution License (the "License"). 6*005d3febSMarek Pospisil * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*005d3febSMarek Pospisil * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * @(#)audit_path.c 2.7 92/02/16 SMI; SunOS CMW 287c478bd9Sstevel@tonic-gate * @(#)audit_path.c 4.2.1.2 91/05/08 SMI; BSM Module 297c478bd9Sstevel@tonic-gate * 307c478bd9Sstevel@tonic-gate * This code does the audit path processes. Part of this is still in 317c478bd9Sstevel@tonic-gate * audit.c and will be moved here when time permits. 327c478bd9Sstevel@tonic-gate * 337c478bd9Sstevel@tonic-gate * Note that audit debuging is enabled here. We will turn it off at 347c478bd9Sstevel@tonic-gate * beta shipment. 357c478bd9Sstevel@tonic-gate */ 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include <sys/types.h> 387c478bd9Sstevel@tonic-gate #include <sys/param.h> 397c478bd9Sstevel@tonic-gate #include <sys/systm.h> 407c478bd9Sstevel@tonic-gate #include <sys/user.h> 417c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 427c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 437c478bd9Sstevel@tonic-gate #include <sys/kmem.h> /* for KM_SLEEP */ 447c478bd9Sstevel@tonic-gate #include <sys/proc.h> 457c478bd9Sstevel@tonic-gate #include <sys/uio.h> 467c478bd9Sstevel@tonic-gate #include <sys/file.h> 477c478bd9Sstevel@tonic-gate #include <sys/stat.h> 487c478bd9Sstevel@tonic-gate #include <sys/pathname.h> 497c478bd9Sstevel@tonic-gate #include <sys/acct.h> 507c478bd9Sstevel@tonic-gate #include <c2/audit.h> 517c478bd9Sstevel@tonic-gate #include <c2/audit_kernel.h> 527c478bd9Sstevel@tonic-gate #include <c2/audit_record.h> 537c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 547c478bd9Sstevel@tonic-gate #include <sys/atomic.h> 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate int 587c478bd9Sstevel@tonic-gate au_token_size(m) 597c478bd9Sstevel@tonic-gate token_t *m; 607c478bd9Sstevel@tonic-gate { 617c478bd9Sstevel@tonic-gate int i; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate if (m == (token_t *)0) 647c478bd9Sstevel@tonic-gate return (0); 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate for (i = 0; m != (token_t *)0; m = m->next_buf) 677c478bd9Sstevel@tonic-gate i += m->len; 687c478bd9Sstevel@tonic-gate return (i); 697c478bd9Sstevel@tonic-gate } 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate token_t * 727c478bd9Sstevel@tonic-gate au_set(cp, size) 737c478bd9Sstevel@tonic-gate caddr_t cp; 747c478bd9Sstevel@tonic-gate uint_t size; 757c478bd9Sstevel@tonic-gate { 767c478bd9Sstevel@tonic-gate au_buff_t *head; 777c478bd9Sstevel@tonic-gate au_buff_t *tail; 787c478bd9Sstevel@tonic-gate au_buff_t *m; 797c478bd9Sstevel@tonic-gate uint_t l; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate head = NULL; 827c478bd9Sstevel@tonic-gate tail = NULL; /* only to satisfy lint */ 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate while (size) { 857c478bd9Sstevel@tonic-gate m = au_get_buff(); 867c478bd9Sstevel@tonic-gate l = MIN(size, AU_BUFSIZE); 877c478bd9Sstevel@tonic-gate bcopy(cp, memtod(m, char *), l); 887c478bd9Sstevel@tonic-gate m->len = l; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate if (head) 917c478bd9Sstevel@tonic-gate tail->next_buf = m; /* tail set if head set */ 927c478bd9Sstevel@tonic-gate else 937c478bd9Sstevel@tonic-gate head = m; 947c478bd9Sstevel@tonic-gate tail = m; 957c478bd9Sstevel@tonic-gate size -= l; 967c478bd9Sstevel@tonic-gate cp += l; 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate return (head); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate token_t * 1037c478bd9Sstevel@tonic-gate au_append_token(chain, m) 1047c478bd9Sstevel@tonic-gate token_t *chain; 1057c478bd9Sstevel@tonic-gate token_t *m; 1067c478bd9Sstevel@tonic-gate { 1077c478bd9Sstevel@tonic-gate token_t *mbp; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate if (chain == (token_t *)0) 1107c478bd9Sstevel@tonic-gate return (m); 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate if (m == (token_t *)0) 1137c478bd9Sstevel@tonic-gate return (chain); 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate for (mbp = chain; mbp->next_buf != (token_t *)0; mbp = mbp->next_buf) 1167c478bd9Sstevel@tonic-gate ; 1177c478bd9Sstevel@tonic-gate mbp->next_buf = m; 1187c478bd9Sstevel@tonic-gate return (chain); 1197c478bd9Sstevel@tonic-gate } 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate void 1237c478bd9Sstevel@tonic-gate audit_fixpath(struct audit_path *app, int len) 1247c478bd9Sstevel@tonic-gate { 1257c478bd9Sstevel@tonic-gate int id; /* index of where we are in destination string */ 1267c478bd9Sstevel@tonic-gate int is; /* index of where we are in source string */ 1277c478bd9Sstevel@tonic-gate int cnt; /* # of levels in audit_path */ 1287c478bd9Sstevel@tonic-gate int slashseen; /* have we seen a slash */ 1297c478bd9Sstevel@tonic-gate char *s; /* start of top-level string */ 1307c478bd9Sstevel@tonic-gate char c; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate cnt = app->audp_cnt; 1337c478bd9Sstevel@tonic-gate s = app->audp_sect[cnt - 1]; 1347c478bd9Sstevel@tonic-gate is = (app->audp_sect[cnt] - s) - len; 1357c478bd9Sstevel@tonic-gate if (is <= 2) 1367c478bd9Sstevel@tonic-gate is = 0; /* catch leading // or ./ */ 1377c478bd9Sstevel@tonic-gate slashseen = (is > 0); 1387c478bd9Sstevel@tonic-gate for (id = is; ; is++) { 1397c478bd9Sstevel@tonic-gate if ((c = s[is]) == '\0') { 1407c478bd9Sstevel@tonic-gate /* that's all folks, we've reached the end of input */ 1417c478bd9Sstevel@tonic-gate if (id > 1 && s[id-1] == '/') { 1427c478bd9Sstevel@tonic-gate /* remove terminating / */ 1437c478bd9Sstevel@tonic-gate --id; 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate s[id++] = '\0'; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate if (slashseen) { 1497c478bd9Sstevel@tonic-gate /* previous character was a / */ 1507c478bd9Sstevel@tonic-gate if (c == '/') { 1517c478bd9Sstevel@tonic-gate /* another slash, ignore it */ 1527c478bd9Sstevel@tonic-gate continue; 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate } else if (c == '/') { 1557c478bd9Sstevel@tonic-gate /* we see a /, just copy it and try again */ 1567c478bd9Sstevel@tonic-gate slashseen = 1; 1577c478bd9Sstevel@tonic-gate s[id++] = c; 1587c478bd9Sstevel@tonic-gate continue; 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate if (c == '.') { 1617c478bd9Sstevel@tonic-gate if ((c = s[is+1]) == '\0') { 1627c478bd9Sstevel@tonic-gate /* XXX/. seen */ 1637c478bd9Sstevel@tonic-gate if (id > 1) 1647c478bd9Sstevel@tonic-gate id--; 1657c478bd9Sstevel@tonic-gate continue; 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate if (c == '/') { 1687c478bd9Sstevel@tonic-gate /* XXX/./ seen */ 1697c478bd9Sstevel@tonic-gate is += 1; 1707c478bd9Sstevel@tonic-gate continue; 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate if (c == '.' && (s[is+2] == '\0' || s[is+2] == '/')) { 1737c478bd9Sstevel@tonic-gate /* XXX/.. or XXX/../ seen */ 1747c478bd9Sstevel@tonic-gate is++; 1757c478bd9Sstevel@tonic-gate if (id == 0 && cnt > 1) { 1767c478bd9Sstevel@tonic-gate char *s_attr; 1777c478bd9Sstevel@tonic-gate /* .. refers to attributed object */ 1787c478bd9Sstevel@tonic-gate app->audp_cnt = --cnt; 1797c478bd9Sstevel@tonic-gate s_attr = s; 1807c478bd9Sstevel@tonic-gate s = app->audp_sect[cnt - 1]; 1817c478bd9Sstevel@tonic-gate id = s_attr - s; 1827c478bd9Sstevel@tonic-gate is += id; 1837c478bd9Sstevel@tonic-gate id--; 1847c478bd9Sstevel@tonic-gate slashseen = 0; 1857c478bd9Sstevel@tonic-gate continue; 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate /* backup over previous component */ 1887c478bd9Sstevel@tonic-gate if (id > 0) 1897c478bd9Sstevel@tonic-gate id--; 1907c478bd9Sstevel@tonic-gate while (id > 0 && s[id - 1] != '/') 1917c478bd9Sstevel@tonic-gate id--; 1927c478bd9Sstevel@tonic-gate continue; 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate /* copy component name and terminating /, if any */ 1967c478bd9Sstevel@tonic-gate for (;;) { 1977c478bd9Sstevel@tonic-gate c = s[is++]; 1987c478bd9Sstevel@tonic-gate if (c == '\0' || c == '/') 1997c478bd9Sstevel@tonic-gate break; 2007c478bd9Sstevel@tonic-gate s[id++] = c; 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate /* back up to before terminating '\0' or / */ 2037c478bd9Sstevel@tonic-gate slashseen = 0; 2047c478bd9Sstevel@tonic-gate is -= 2; 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate /* fill empty attribute directory reference */ 2077c478bd9Sstevel@tonic-gate if (id == 1 && cnt > 1) { 2087c478bd9Sstevel@tonic-gate s[0] = '.'; 2097c478bd9Sstevel@tonic-gate s[1] = '\0'; 2107c478bd9Sstevel@tonic-gate id = 2; 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate /* correct end pointer */ 2137c478bd9Sstevel@tonic-gate app->audp_sect[cnt] = s + id; 2147c478bd9Sstevel@tonic-gate } 215