17c478bd9Sstevel@tonic-gate# 287e895dbStz# Copyright 2006 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate# Use is subject to license terms. 47c478bd9Sstevel@tonic-gate# 57c478bd9Sstevel@tonic-gate# CDDL HEADER START 67c478bd9Sstevel@tonic-gate# 77c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 887e895dbStz# Common Development and Distribution License (the "License"). 987e895dbStz# You may not use this file except in compliance with the License. 107c478bd9Sstevel@tonic-gate# 117c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 127c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 137c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 147c478bd9Sstevel@tonic-gate# and limitations under the License. 157c478bd9Sstevel@tonic-gate# 167c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 177c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 187c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 197c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 207c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 217c478bd9Sstevel@tonic-gate# 227c478bd9Sstevel@tonic-gate# CDDL HEADER END 237c478bd9Sstevel@tonic-gate# 247c478bd9Sstevel@tonic-gate# ident "%Z%%M% %I% %E% SMI" 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate# WARNING -- this package implements a Sun private interface; it may 277c478bd9Sstevel@tonic-gate# change without notice. 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gatepackage Sun::Solaris::BSM::_BSMparse; 307c478bd9Sstevel@tonic-gaterequire 5.005; 317c478bd9Sstevel@tonic-gateuse strict; 327c478bd9Sstevel@tonic-gateuse Exporter; 337c478bd9Sstevel@tonic-gateuse Sun::Solaris::Utils qw(gettext); 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gateuse vars qw($VERSION $failedOpen 367c478bd9Sstevel@tonic-gate %EXPORT_TAGS @ISA @EXPORT_OK @EXPORT_FAIL); 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate$VERSION = '1.01'; 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate@ISA = qw(Exporter); 417c478bd9Sstevel@tonic-gatemy @constants = qw(); 427c478bd9Sstevel@tonic-gate@EXPORT_OK = qw(readAttr readEvent readClass filterLabel filterCallName 437c478bd9Sstevel@tonic-gate readControl getPathList readUser ckAttrEvent); 447c478bd9Sstevel@tonic-gate@EXPORT_FAIL = qw($failedOpen); 457c478bd9Sstevel@tonic-gate%EXPORT_TAGS = (ALL => \@EXPORT_OK); 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate$failedOpen = gettext("failed to open %s: %s"); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gatesub new { 507c478bd9Sstevel@tonic-gate my $obj = shift; 517c478bd9Sstevel@tonic-gate my $debug = shift; # bool 527c478bd9Sstevel@tonic-gate my $filters = shift; # options for filtering 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate my $dir = '/etc/security'; 55*1b5f7228Stz my $attrDir = '/usr/lib/audit'; 567c478bd9Sstevel@tonic-gate my $configDir = $dir; 577c478bd9Sstevel@tonic-gate $attrDir = shift if (@_); # override for test 587c478bd9Sstevel@tonic-gate $configDir = shift if (@_); # ditto 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate my $suffix = ''; 617c478bd9Sstevel@tonic-gate $suffix = shift if (@_); # test, again 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate $obj = ref($obj) || $obj; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate my ($recordf, $classf, $controlf, $eventf, $userf) = 667c478bd9Sstevel@tonic-gate ("$attrDir/audit_record_attr$suffix", 677c478bd9Sstevel@tonic-gate "$configDir/audit_class$suffix", 687c478bd9Sstevel@tonic-gate "$configDir/audit_control$suffix", 697c478bd9Sstevel@tonic-gate "$configDir/audit_event$suffix", 707c478bd9Sstevel@tonic-gate "$configDir/audit_user$suffix"); 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate return (bless { 737c478bd9Sstevel@tonic-gate 'attrFile' => $recordf, 747c478bd9Sstevel@tonic-gate 'classFile' => $classf, 757c478bd9Sstevel@tonic-gate 'classFilter' => $filters->{'classFilter'}, 767c478bd9Sstevel@tonic-gate 'controlFile' => $controlf, 777c478bd9Sstevel@tonic-gate 'debug' => $debug, 787c478bd9Sstevel@tonic-gate 'eventFile' => $eventf, 797c478bd9Sstevel@tonic-gate 'eventFilter' => $filters->{'eventFilter'}, 807c478bd9Sstevel@tonic-gate 'idFilter' => $filters->{'idFilter'}, 817c478bd9Sstevel@tonic-gate 'havePath' => 0, 827c478bd9Sstevel@tonic-gate 'kernelDefault' => '', 837c478bd9Sstevel@tonic-gate 'userDefault' => '', 847c478bd9Sstevel@tonic-gate 'userFile' => $userf}, $obj); 857c478bd9Sstevel@tonic-gate} 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate# readAttr 887c478bd9Sstevel@tonic-gate# read the hand edited attrFile file 897c478bd9Sstevel@tonic-gate# 907c478bd9Sstevel@tonic-gate# return a hash reference 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gatesub readAttr { 937c478bd9Sstevel@tonic-gate my $obj = shift; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate my $file = $obj->{'attrFile'}; 967c478bd9Sstevel@tonic-gate my $fileHandle = do {local *FileHandle; *FileHandle}; 977c478bd9Sstevel@tonic-gate open($fileHandle, $file) or die sprintf("$failedOpen\n", $file, $!); 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate my $count = 0; 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate my $attrState = -1; 1027c478bd9Sstevel@tonic-gate my $caseState = 0; 1037c478bd9Sstevel@tonic-gate my $label; 1047c478bd9Sstevel@tonic-gate my $callName = ''; 1057c478bd9Sstevel@tonic-gate my $skip = ''; 1067c478bd9Sstevel@tonic-gate my $description = 'none'; 1077c478bd9Sstevel@tonic-gate my $format = 'none'; 1087c478bd9Sstevel@tonic-gate my $comment = ''; 1097c478bd9Sstevel@tonic-gate my $title = 'none'; 1107c478bd9Sstevel@tonic-gate my $note = ''; 1117c478bd9Sstevel@tonic-gate my $case = ''; 1127c478bd9Sstevel@tonic-gate my @case = (); 1137c478bd9Sstevel@tonic-gate my %skipClass; 1147c478bd9Sstevel@tonic-gate my %attr = (); 1157c478bd9Sstevel@tonic-gate my %token = (); 1167c478bd9Sstevel@tonic-gate my $classFilter = $obj->{'classFilter'}; 1177c478bd9Sstevel@tonic-gate $classFilter = '' unless (defined ($classFilter)); 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate my %noteAlias = (); 1207c478bd9Sstevel@tonic-gate while (<$fileHandle>) { 1217c478bd9Sstevel@tonic-gate chomp; 1227c478bd9Sstevel@tonic-gate s/#.*//; # remove comment 1237c478bd9Sstevel@tonic-gate next if (/^\s*$/); 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate if ($attrState < 0) { # initial state: header info 1267c478bd9Sstevel@tonic-gate if (/^\s*skipClass\s*=\s*(.*)/i) { 1277c478bd9Sstevel@tonic-gate my $class = $1; 1287c478bd9Sstevel@tonic-gate # don't skip what you're searching for 12987e895dbStz next if (index(lc($classFilter),lc($class)) > -1); 1307c478bd9Sstevel@tonic-gate $skipClass{$1} = 1; 1317c478bd9Sstevel@tonic-gate next; 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate elsif (/^\s*token\s*=\s*(.*)/i) { 1347c478bd9Sstevel@tonic-gate my ($attr, $value) = split(/\s*:\s*/, $1); 1357c478bd9Sstevel@tonic-gate $token{$attr} = $value; 1367c478bd9Sstevel@tonic-gate next; 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate elsif (/^\s*message\s*=\s*(.*)/i) { 1397c478bd9Sstevel@tonic-gate my ($attr, $value) = split(/\s*:\s*/, $1); 1407c478bd9Sstevel@tonic-gate $noteAlias{$attr} = $value; 1417c478bd9Sstevel@tonic-gate next; 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate elsif (/^\s*kernel\s*=\s*(.*)/i) { 1447c478bd9Sstevel@tonic-gate my ($attr, $value) = split(/\s*:\s*/, $1); 1457c478bd9Sstevel@tonic-gate $obj->{'kernelDefault'} = $1; 1467c478bd9Sstevel@tonic-gate next; 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate elsif (/^\s*user\s*=\s*(.*)/i) { 1497c478bd9Sstevel@tonic-gate my ($attr, $value) = split(/\s*:\s*/, $1); 1507c478bd9Sstevel@tonic-gate $obj->{'userDefault'} = $1; 1517c478bd9Sstevel@tonic-gate next; 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate if (/^\s*label\s*=\s*(.*)/i) { 1557c478bd9Sstevel@tonic-gate $attrState = 0 if ($attrState < 0); 1567c478bd9Sstevel@tonic-gate my $newLabel = $1; 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate if ($obj->{'debug'}) { 1597c478bd9Sstevel@tonic-gate print STDERR qq{ 1607c478bd9Sstevel@tonic-gate$newLabel is duplicated in the attribute file (line $.) 1617c478bd9Sstevel@tonic-gate } if ($attr{$newLabel}); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate # if $attrState not zero, an unwritten record exists 1647c478bd9Sstevel@tonic-gate if ($attrState) { 1657c478bd9Sstevel@tonic-gate $callName = $obj->filterCallName($label, 1667c478bd9Sstevel@tonic-gate $callName); 1677c478bd9Sstevel@tonic-gate push(@case, [$case, $format, $comment, $note]); 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate if ($obj->filterLabel($label)) { 1707c478bd9Sstevel@tonic-gate $attr{$label} = 1717c478bd9Sstevel@tonic-gate [$callName, $description, $title, 1727c478bd9Sstevel@tonic-gate $skip, @case]; 1737c478bd9Sstevel@tonic-gate $count++; 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate $format = $description = $title = 'none'; 1767c478bd9Sstevel@tonic-gate $case = $note = $comment = $skip = $callName 1777c478bd9Sstevel@tonic-gate = ''; 1787c478bd9Sstevel@tonic-gate @case = (); 1797c478bd9Sstevel@tonic-gate $caseState = 0; 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate $label = $newLabel; 1827c478bd9Sstevel@tonic-gate $attrState = 1; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate elsif (/^\s*skip\s*=\s*(.*)/i) { 1857c478bd9Sstevel@tonic-gate $skip = $1; 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate elsif (/^\s*syscall\s*=\s*(.*)/i) { 1887c478bd9Sstevel@tonic-gate $callName = $1; 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate elsif (/^\s*program\s*=\s*(.*)/i) { 1917c478bd9Sstevel@tonic-gate $callName = $1; 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate elsif (/^\s*title\s*=\s*(.*)/i) { 1947c478bd9Sstevel@tonic-gate $title = $1; 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate elsif (/^\s*see\s*=\s*(.*)/i) { 1977c478bd9Sstevel@tonic-gate $description = $1; 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate elsif (/^\s*format\s*=\s*(.*)/i) { 2007c478bd9Sstevel@tonic-gate $format = $1; 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate elsif (/^\s*comment\s*=\s*(.*)/i) { 2037c478bd9Sstevel@tonic-gate $comment .= $1; 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate elsif (/^\s*note\s*=\s*(.*)/i) { 2067c478bd9Sstevel@tonic-gate $note .= $1; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate elsif (/^\s*case\s*=\s*(.*)/i) { 2097c478bd9Sstevel@tonic-gate if ($caseState) { 2107c478bd9Sstevel@tonic-gate push(@case, [$case, $format, $comment, $note]); 2117c478bd9Sstevel@tonic-gate $format = 'none'; 2127c478bd9Sstevel@tonic-gate $comment = $note = ''; 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate $case = $1; 2157c478bd9Sstevel@tonic-gate $caseState = 1; 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate if ($attrState) { 2197c478bd9Sstevel@tonic-gate $callName = $obj->filterCallName($label, $callName); 2207c478bd9Sstevel@tonic-gate push(@case, [$case, $format, $comment, $note]); 2217c478bd9Sstevel@tonic-gate if ($obj->filterLabel($label)) { 2227c478bd9Sstevel@tonic-gate $attr{$label} = [$callName, $description, $title, $skip, 2237c478bd9Sstevel@tonic-gate @case]; 2247c478bd9Sstevel@tonic-gate $count++; 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate close $fileHandle; 2287c478bd9Sstevel@tonic-gate print STDERR "found $count audit attribute entries\n" if ($obj->{'debug'}); 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate return ($obj->{'attr'} = \%attr, \%token, \%skipClass, \%noteAlias); 2317c478bd9Sstevel@tonic-gate} 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate# readEvent 2347c478bd9Sstevel@tonic-gate# read eventFile and extract audit event information, including 2357c478bd9Sstevel@tonic-gate# which classes are associated with each event and what call is 2367c478bd9Sstevel@tonic-gate# related. 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gatesub readEvent { 2397c478bd9Sstevel@tonic-gate my $obj = shift; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate my %event = (); 2427c478bd9Sstevel@tonic-gate my $file = $obj->{'eventFile'}; 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate my $fileHandle = do {local *FileHandle; *FileHandle}; 2457c478bd9Sstevel@tonic-gate open($fileHandle, $file) or die sprintf("$failedOpen\n", $file, $!); 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate my $count = 0; 2487c478bd9Sstevel@tonic-gate 24987e895dbStz unless (defined $obj->{'class'} && (scalar keys %{$obj->{'class'}} > 1)) { 25087e895dbStz $obj->readClass(); 25187e895dbStz } 25287e895dbStz 25387e895dbStz my @classFilterMasks = (); 2547c478bd9Sstevel@tonic-gate my $classFilter = $obj->{'classFilter'}; 2557c478bd9Sstevel@tonic-gate if ($classFilter) { 25687e895dbStz foreach (split(',', $classFilter)) { 25787e895dbStz push @classFilterMasks, $obj->{'class'}{$_}; 25887e895dbStz } 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate # ignore customer-supplied audit events (id > 32767) 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate while (<$fileHandle>) { 2637c478bd9Sstevel@tonic-gate chomp; 2647c478bd9Sstevel@tonic-gate s/#.*//; # remove comment 2657c478bd9Sstevel@tonic-gate next if (/^\s*$/); 2667c478bd9Sstevel@tonic-gate if (/^\s*(\d+):(\w+):([^:]+):(.*)/) { 2677c478bd9Sstevel@tonic-gate my $id = $1; 2687c478bd9Sstevel@tonic-gate my $label = $2; 2697c478bd9Sstevel@tonic-gate my $description = $3; 2707c478bd9Sstevel@tonic-gate my $class = $4; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate if ($id !~ /\d+/) { 2737c478bd9Sstevel@tonic-gate print STDERR "$id is not numeric (line $.)\n"; 2747c478bd9Sstevel@tonic-gate next; 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate next if ($id > 32767); 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate $class =~ s/\s*$//; 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate if ($obj->{'debug'}) { 2817c478bd9Sstevel@tonic-gate print STDERR qq{ 2827c478bd9Sstevel@tonic-gate$label is duplicated in the event file (line $.) 2837c478bd9Sstevel@tonic-gate } if ($event{$label}); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate next unless ($obj->filterLabel($label)); 28687e895dbStz my $mask = 0; 2877c478bd9Sstevel@tonic-gate if ($classFilter) { 28887e895dbStz foreach (split(/\s*,\s*/, $class)) { 28987e895dbStz $mask |= $obj->{'class'}{$_}; 29087e895dbStz } 29187e895dbStz my $skip = 0; 29287e895dbStz foreach my $filterMask (@classFilterMasks) { 29387e895dbStz unless ($mask & $filterMask) { 29487e895dbStz $skip = 1; 29587e895dbStz last; 29687e895dbStz } 29787e895dbStz } 29887e895dbStz next if $skip; 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate if ($obj->{'idFilter'}) { 3017c478bd9Sstevel@tonic-gate next unless ($obj->{'idFilter'} == $id); 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate $event{$label} = [$id, $class, $description]; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate $count++; 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate close $fileHandle; 3097c478bd9Sstevel@tonic-gate print STDERR "found $count audit events\n" if ($obj->{'debug'}); 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate return ($obj->{'event'} = \%event); 3127c478bd9Sstevel@tonic-gate} 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate# readClass 3157c478bd9Sstevel@tonic-gate# read classFile and extract audit class information 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gatesub readClass { 3187c478bd9Sstevel@tonic-gate my $obj = shift; 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate my %class = (); 3217c478bd9Sstevel@tonic-gate my $file = $obj->{'classFile'}; 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate my $fileHandle = do {local *FileHandle; *FileHandle}; 3247c478bd9Sstevel@tonic-gate open($fileHandle, $file) or die sprintf("$failedOpen\n", $file, $!); 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate my $count = 0; 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate while (<$fileHandle>) { 3297c478bd9Sstevel@tonic-gate chomp; 3307c478bd9Sstevel@tonic-gate s/#.*//; # remove comment 3317c478bd9Sstevel@tonic-gate next if (/^\s*$/); 3327c478bd9Sstevel@tonic-gate my ($mask1, $class) = split(/:/); # third field not used 3337c478bd9Sstevel@tonic-gate my $mask2 = hex($mask1); # integer 3347c478bd9Sstevel@tonic-gate $class{$class} = $mask2; 3357c478bd9Sstevel@tonic-gate $count++; 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate close $fileHandle; 3387c478bd9Sstevel@tonic-gate print STDERR "found $count audit classes\n" if ($obj->{'debug'}); 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate return ($obj->{'class'} = \%class); 3417c478bd9Sstevel@tonic-gate} 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gatesub filterLabel { 3447c478bd9Sstevel@tonic-gate my $obj = shift; 3457c478bd9Sstevel@tonic-gate my $label = shift; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate my $eventFilter = $obj->{'eventFilter'}; 3487c478bd9Sstevel@tonic-gate my $keepIt = 1; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate $keepIt = 0 if ($eventFilter && ($label !~ /$eventFilter/i)); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate return ($keepIt); 3537c478bd9Sstevel@tonic-gate} 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate# Normally, the root of the event label is the system call. The 3567c478bd9Sstevel@tonic-gate# attrFile attribute syscall or program overrides this. 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gatesub filterCallName { 3597c478bd9Sstevel@tonic-gate my $obj = shift; 3607c478bd9Sstevel@tonic-gate my $label = shift; 3617c478bd9Sstevel@tonic-gate my $callName = shift; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate return ($callName) if ($callName); 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate $label =~ /AUE_(.*)/; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate my $name = $1; 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate return (lc ($name)); 3707c478bd9Sstevel@tonic-gate} 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate# readControl 3737c478bd9Sstevel@tonic-gate# read controlFile and extract flags and naflags information 3747c478bd9Sstevel@tonic-gate# at present, minfree, maxfree and the audit partitions are not 3757c478bd9Sstevel@tonic-gate# checked. 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gatesub readControl { 3787c478bd9Sstevel@tonic-gate my $obj = shift; 3797c478bd9Sstevel@tonic-gate my $failMode = shift; 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate my $cError = 0; 3827c478bd9Sstevel@tonic-gate my $errors = ''; 3837c478bd9Sstevel@tonic-gate my $file = $obj->{'controlFile'}; 3847c478bd9Sstevel@tonic-gate my $invalidClass = gettext('invalid class, %s, in audit_control: %s'); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate my $fileHandle = do {local *FileHandle; *FileHandle}; 3877c478bd9Sstevel@tonic-gate unless (open($fileHandle, $file)) { 3887c478bd9Sstevel@tonic-gate die sprintf("$failedOpen\n", $file, $!) 3897c478bd9Sstevel@tonic-gate unless ($failMode eq 'ignore'); 3907c478bd9Sstevel@tonic-gate return (0, ''); 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate my %class = $obj->{'class'}; 3937c478bd9Sstevel@tonic-gate my @paths = $obj->{'paths'}; 3947c478bd9Sstevel@tonic-gate while (<$fileHandle>) { 3957c478bd9Sstevel@tonic-gate chomp; 3967c478bd9Sstevel@tonic-gate s/#.*//; # remove comment 3977c478bd9Sstevel@tonic-gate next if (/^\s*$/); 3987c478bd9Sstevel@tonic-gate if ((/^\s*flags:/i) || (/^\s*naflags:/i)) { 3997c478bd9Sstevel@tonic-gate my ($class) = /flags:\s*(.*)/; 4007c478bd9Sstevel@tonic-gate my @class = split(/\s*,\s*/, $class); 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate foreach $class (@class) { 40387e895dbStz $class =~ s/^[-+^]+//; 4047c478bd9Sstevel@tonic-gate unless (defined ($class{$class})) { 4057c478bd9Sstevel@tonic-gate $errors .= 4067c478bd9Sstevel@tonic-gate sprintf("$invalidClass\n", 4077c478bd9Sstevel@tonic-gate $class, $_); 4087c478bd9Sstevel@tonic-gate $cError++; 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate elsif (/^\s*dir:\s*(.*)/) { 4137c478bd9Sstevel@tonic-gate push (@paths, $1); 4147c478bd9Sstevel@tonic-gate $obj->{'havePath'} = 1; 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate close $fileHandle; 4187c478bd9Sstevel@tonic-gate return ($cError, $errors); 4197c478bd9Sstevel@tonic-gate} 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gatesub getPathList { 4227c478bd9Sstevel@tonic-gate my $obj = shift; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate $obj->readControl() unless ($obj->{'havePath'}); 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate return ($obj->{'paths'}); 4277c478bd9Sstevel@tonic-gate} 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate# readUser 4307c478bd9Sstevel@tonic-gate# read userFile and extract audit information for validation 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gatesub readUser { 4337c478bd9Sstevel@tonic-gate my $obj = shift; 4347c478bd9Sstevel@tonic-gate my $failMode = shift; 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate my $cError = 0; 4377c478bd9Sstevel@tonic-gate my $error = ''; 4387c478bd9Sstevel@tonic-gate my $file = $obj->{'userFile'}; 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate my $fileHandle = do {local *FileHandle; *FileHandle}; 4417c478bd9Sstevel@tonic-gate unless (open($fileHandle, $file)) { 4427c478bd9Sstevel@tonic-gate die sprintf("$failedOpen\n", $file, $!) 4437c478bd9Sstevel@tonic-gate unless ($failMode eq 'ignore'); 4447c478bd9Sstevel@tonic-gate return (0, ''); 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate # these strings are defined here mostly to avoid indentation problems 4477c478bd9Sstevel@tonic-gate my $emptyErr = gettext('empty audit mask in audit_user: %s'); 4487c478bd9Sstevel@tonic-gate my $syntaxErr1 = gettext( 4497c478bd9Sstevel@tonic-gate 'incorrect syntax (exactly two colons req\'d) in audit_user: %s'); 4507c478bd9Sstevel@tonic-gate my $syntaxErr2 = gettext('incorrect syntax in audit_user: %s'); 4517c478bd9Sstevel@tonic-gate my $invalidErr = gettext('invalid class, %s, in audit_user: %s'); 4527c478bd9Sstevel@tonic-gate my $undefined = gettext('undefined user name in audit_user: %s'); 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate my %class = $obj->{'class'}; 4557c478bd9Sstevel@tonic-gate while (<$fileHandle>) { 4567c478bd9Sstevel@tonic-gate chomp; 4577c478bd9Sstevel@tonic-gate s/#.*//; # remove comment 4587c478bd9Sstevel@tonic-gate next if (/^\s*$/); 4597c478bd9Sstevel@tonic-gate my $colonCount = tr/:/:/; 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate if ($colonCount != 2) { 4627c478bd9Sstevel@tonic-gate $error .= sprintf("$syntaxErr1\n", $_); 4637c478bd9Sstevel@tonic-gate $cError++; 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate my ($user, $always, $never) = split(/\s*:\s*/); 4667c478bd9Sstevel@tonic-gate unless (defined($user)) { 4677c478bd9Sstevel@tonic-gate $error .= sprintf("$syntaxErr2\n", $_); 4687c478bd9Sstevel@tonic-gate $cError++; 4697c478bd9Sstevel@tonic-gate next; 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate $error .= sprintf("$emptyErr\n", $_) unless ($always); 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate my ($name) = getpwnam($user); 4747c478bd9Sstevel@tonic-gate unless (defined($name)) { 4757c478bd9Sstevel@tonic-gate $error .= sprintf("$undefined\n", $user); 4767c478bd9Sstevel@tonic-gate $cError++; 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate unless (defined($always) && defined($never)) { 4797c478bd9Sstevel@tonic-gate $error .= sprintf("$emptyErr\n", $_); 4807c478bd9Sstevel@tonic-gate $cError++; 4817c478bd9Sstevel@tonic-gate next; 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate my $verify = $always . ',' . $never; 4847c478bd9Sstevel@tonic-gate my @class = split(/\s*,\s*/, $verify); 4857c478bd9Sstevel@tonic-gate my $thisClass; 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate foreach $thisClass (@class) { 48887e895dbStz $thisClass =~ s/^[-+^]+//; 4897c478bd9Sstevel@tonic-gate unless (defined $class{$thisClass}) { 4907c478bd9Sstevel@tonic-gate $error .= sprintf("$invalidErr\n", $thisClass, 4917c478bd9Sstevel@tonic-gate $_); 4927c478bd9Sstevel@tonic-gate $cError++; 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate close $fileHandle; 4977c478bd9Sstevel@tonic-gate return ($cError, $error); 4987c478bd9Sstevel@tonic-gate} 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate# ckAttrEvent complains if controlFile and attrFile don''t contain the 5017c478bd9Sstevel@tonic-gate# same list of events. 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gatesub ckAttrEvent { 5047c478bd9Sstevel@tonic-gate my $obj = shift; 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate my $cError = 0; 5077c478bd9Sstevel@tonic-gate my $error = ''; 5087c478bd9Sstevel@tonic-gate my $cAttr = 0; 5097c478bd9Sstevel@tonic-gate my $label; 5107c478bd9Sstevel@tonic-gate my $attrErr = gettext( 5117c478bd9Sstevel@tonic-gate '%s entry in attribute file but not in event file'); 5127c478bd9Sstevel@tonic-gate my $eventErr = gettext( 5137c478bd9Sstevel@tonic-gate '%s entry in event file but not in attribute file'); 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate my %attr = %{$obj->{'attr'}}; 5167c478bd9Sstevel@tonic-gate my %event = %{$obj->{'event'}}; 5177c478bd9Sstevel@tonic-gate foreach $label (keys %attr) { 5187c478bd9Sstevel@tonic-gate $cAttr++; 5197c478bd9Sstevel@tonic-gate unless ($event{$label}) { 5207c478bd9Sstevel@tonic-gate $error .= sprintf("$attrErr\n", $label); 5217c478bd9Sstevel@tonic-gate $cError++; 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate my $cEvent = 0; 5257c478bd9Sstevel@tonic-gate foreach $label (keys %event) { 5267c478bd9Sstevel@tonic-gate $cEvent++; 5277c478bd9Sstevel@tonic-gate unless ($attr{$label}) { 5287c478bd9Sstevel@tonic-gate $error .= sprintf("$eventErr\n", $label); 5297c478bd9Sstevel@tonic-gate $cError++; 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate # debug only; not I18N'd 5337c478bd9Sstevel@tonic-gate print STDERR 5347c478bd9Sstevel@tonic-gate "$cAttr audit_record_attr entries and $cEvent audit_event entries\n" 5357c478bd9Sstevel@tonic-gate if ($obj->{'debug'}); 5367c478bd9Sstevel@tonic-gate return ($cError, $error); 5377c478bd9Sstevel@tonic-gate} 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate1; 540