diff --exclude-from=exclude -N -u -r nsapolicycoreutils/audit2allow/audit2allow policycoreutils-1.27.28/audit2allow/audit2allow --- nsapolicycoreutils/audit2allow/audit2allow 2005-09-12 16:33:30.000000000 -0400 +++ policycoreutils-1.27.28/audit2allow/audit2allow 2005-11-17 10:26:24.000000000 -0500 @@ -1,7 +1,12 @@ -#!/usr/bin/perl - -# Adapted from: +#! /usr/bin/env python +# Copyright (C) 2005 Red Hat +# see file 'COPYING' for use and warranty information +# +# Audit2allow is a rewrite of prior perl script. +# +# Based off original audit2allow perl script: which credits # newrules.pl, Copyright (C) 2001 Justin R. Smith (jsmith@mcs.drexel.edu) +# 2003 Oct 11: Add -l option by Yuichi Nakamura(ynakam@users.sourceforge.jp) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -17,148 +22,316 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA # 02111-1307 USA -# 2003 Oct 11: Add -l option by Yuichi Nakamura(ynakam@users.sourceforge.jp) - - -$load_policy_pattern="avc:.*granted.*{.*load_policy.*}"; - -while ($opt = shift @ARGV) { - if ($opt eq "-d") { $read_dmesg++; } - elsif ($opt eq "-v") { $verbose++; } - elsif ($opt eq "-i") { $input = shift @ARGV; } - elsif ($opt eq "-o") { $output= shift @ARGV; } - elsif ($opt eq "-l") { $load_policy++; } - elsif ($opt eq "--help") { &printUsage; } - else { print "unknown option, '$opt'\n\n"; &printUsage; } -} - -if ($read_dmesg && $input) { - print "Error, can't read from both dmesg and $input\n\n"; - &printUsage; -} - -if ($read_dmesg) { open (IN, "/bin/dmesg|"); } -elsif ($input) { open (IN, "$input"); } -else { open (IN, "-"); } # STDIN - -if ($output) { open (OUT, ">>$output"); } -else { open (OUT, ">-"); } # STDOUT - -if($load_policy){ #store logs after last "load_policy" in @log_buf - while ($line = ) { - if($line=~/$load_policy_pattern/) { - #stored logs are unnecessary - undef @log_buf; - } - else - { - push @log_buf,$line; - } - } -} - -while ($line=&readNewline) { - next unless ($line =~ m/avc:\s*denied\s*\{((\w|\s)*)\}/); - @types=split /\ /,$line; - $info=""; - $group=""; - $command=""; - foreach $i(0..$#types){ - next if($types[$i]!~/[=\{]/); - if($types[$i]=~/^\{/){ - $j=$i+1; - while($types[$j]!~/\}/){ - $command.=" $types[$j]"; - $j++; - } - next; - } - my($a,$b) = split /=/,$types[$i]; - - next if($a eq "pid"); - next if($a eq "dev"); - next if($a eq "ino"); +# +# +import commands, sys, os, pwd, string, getopt, re +class allow: + def __init__(self, source, target, seclass): + self.source=source + self.target=target + self.seclass=seclass + self.avcinfo={} + def add(self, avc): + for a in avc[0]: + if a not in self.avcinfo.keys(): + self.avcinfo[a]=[] + + self.avcinfo[a].append(avc[1:]) + + def getAccess(self): + if len(self.avcinfo.keys()) == 1: + for i in self.avcinfo.keys(): + return i + else: + keys=self.avcinfo.keys() + keys.sort() + ret="{" + for i in keys: + ret=ret + " " + i + ret=ret+" }" + return ret + def out(self, verbose=0): + ret="" + ret=ret+"allow %s %s:%s %s;" % (self.source, self.gettarget(), self.seclass, self.getAccess()) + if verbose: + keys=self.avcinfo.keys() + keys.sort() + for i in keys: + for x in self.avcinfo[i]: + ret=ret+"\n\t#TYPE=AVC MSG=%s " % x[0] + if len(x[1]): + ret=ret+"COMM=%s " % x[1] + if len(x[2]): + ret=ret+"NAME=%s " % x[2] + ret=ret + " : " + i + return ret + + def gettarget(self): + if self.source == self.target: + return "self" + else: + return self.target - if(($a eq "scontext")||($a eq "tcontext")||($a eq "tclass")){ - if($a ne "tclass"){ - my($c,$c,$c) = split /:/, $b; - $b=$c; - } - $b=~s/\n//; - $group.="|$b"; - next; - } - $b=~s/:\[\d+\]//; - $a=uc $a; - $info.="$a=$b "; - } - - my($c,$c,$c,$c) = split /\|/, $group; - $info=~s/\ $c=\S+\ //gi; - # escape regexp patterns -- - $info=~s/([^\w])/\\$1/g; - - @atypes=split /\ /,$command; - foreach $i(0..$#atypes){ - $rules{$group}{$atypes[$i]}++; - } - - $info.=" "; - if($occur{$group}!~$info){ - $occur{$group}.="\t#$info: $command\n"; - } - else{ - my ($a,$b) = split /$info:\ /, $occur{$group}; - my ($temp) = split /\n/, $b; +class allowRecords: + def __init__(self, input, last_reload=0, verbose=0): + self.last_reload=last_reload + self.allowRules={} + self.seclasses={} + self.types=[] + self.roles=[] + self.load(input) + + def load(self, input): + avc=[] + found=0 + line = input.readline() + while line: + rec=line.split() + for i in rec: + if i=="avc:" or i=="message=avc:": + found=1 + else: + avc.append(i) + if found: + self.add(avc) + found=0 + avc=[] + line = input.readline() + + + def add(self,avc): + scon="" + tcon="" + seclass="" + comm="" + name="" + msg="" + access=[] + if "security_compute_sid" in avc: + return + + if "granted" in avc: + if "load_policy" in avc and self.last_reload: + self.allowRules={} + return + for i in range (0, len(avc)): + if avc[i]=="{": + i=i+1 + while i; - } - return $newline; -} - -sub printUsage { - print "audit2allow [-d] [-v] [-l] [-i ] [-o ] - -d read input from output of /bin/dmesg - -v verbose output - -l read input only after last \"load_policy\" - -i read input from - -o append output to \n"; - exit; -} - + def out(self, require=0, module=""): + rec="" + if len(self.allowRules.keys())==0: + raise(ValueError("No AVC messages found.")) + if module!="": + rec += self.gen_module(module) + rec += self.gen_requires() + else: + if requires: + rec+=self.gen_requires() + + for i in self.allowRules.keys(): + rec += self.allowRules[i].out(verbose)+"\n" + return rec + +if __name__ == '__main__': + + def usage(): + print 'audit2allow [-adhilrv] [-i ] [[-m|-M] ] [-o ]\n\ + -a, --all read input from audit and message log, conflicts with -i\n\ + -d, --dmesg read input from output of /bin/dmesg\n\ + -h, --help display this message\n\ + -i, --input read input from conflicts with -a\n\ + -l, --lastreload read input only after last \"load_policy\"\n\ + -m, --module generate module/require output \n\ + -M generate loadable module package, conflicts with -o\n\ + -o, --output append output to , conflicts with -M\n\ + -r, --requires generate require output \n\ + -v, --verbose verbose output\n\ + ' + sys.exit(1) + + def errorExit(error): + sys.stderr.write("%s: " % sys.argv[0]) + sys.stderr.write("%s\n" % error) + sys.stderr.flush() + sys.exit(1) + + # + # + # + try: + last_reload=0 + input=sys.stdin + output=sys.stdout + module="" + requires=0 + verbose=0 + auditlogs=0 + buildPP=0 + input_ind=0 + output_ind=0 + gopts, cmds = getopt.getopt(sys.argv[1:], + 'adhi:lm:M:o:rv', + ['all', + 'dmesg', + 'help', + 'input=', + 'lastreload', + 'module=', + 'output=', + 'requires' + 'verbose' + ]) + for o,a in gopts: + if o == "-a" or o == "--all": + if input_ind: + usage() + input=open("/var/log/messages", "r") + auditlogs=1 + if o == "-d" or o == "--dmesg": + input=os.popen("/bin/dmesg", "r") + if o == "-h" or o == "--help": + usage() + if o == "-i"or o == "--input": + if auditlogs: + usage() + input_ind=1 + input=open(a, "r") + if o == '--lastreload' or o == "-l": + last_reload=1 + if o == "-m" or o == "--module": + if module != "": + usage() + module=a + if o == "-M": + if module != "" or output_ind: + usage() + module=a + outfile=a+".te" + buildPP=1 + output=open(outfile, "w") + if o == "-r" or o == "--requires": + requires=1 + if o == "-o" or o == "--output": + if module != "": + usage() + output=open(a, "a") + output_ind=1 + if o == "-v" or o == "--verbose": + verbose=1 + if len(cmds) != 0: + usage() + out=allowRecords(input, last_reload, verbose) + if auditlogs: + input=open("/var/log/audit/audit.log", "r") + out.load(input) + if buildPP: + print ("Generating type enforcment file: %s.te" % module) + output.write(out.out(requires, module)) + if buildPP: + print ("Compiling policy: checkmodule -M -m -o %s.mod %s.te" % (module, module)) + rc=commands.getstatusoutput("checkmodule -M -m -o %s.mod %s.te" % (module, module)) + if rc[0]==0: + print ("Building package: semodule_package -o %s.pp -m %s.mod" % (module, module)) + rc=commands.getstatusoutput("semodule_package -o %s.pp -m %s.mod" % (module, module)) + if rc[0]==0: + print ("\n*************** IMPORTANT ***********************\n") + print ("In order to load this newly created policy package,\nyou are required to execute \n\n\"semodule -i %s.pp\"\n\nto load the policy\n" % module) + else: + errorExit(rc[1]) + else: + errorExit(rc[1]) + + except getopt.error, error: + errorExit("Options Error " + error.msg) + except ValueError, error: + errorExit(error.args[0]) + except IOError, error: + errorExit(error.args[1]) + except KeyboardInterrupt, error: + sys.exit(0) diff --exclude-from=exclude -N -u -r nsapolicycoreutils/audit2allow/audit2allow.perl policycoreutils-1.27.28/audit2allow/audit2allow.perl --- nsapolicycoreutils/audit2allow/audit2allow.perl 1969-12-31 19:00:00.000000000 -0500 +++ policycoreutils-1.27.28/audit2allow/audit2allow.perl 2005-11-16 22:33:25.000000000 -0500 @@ -0,0 +1,164 @@ +#!/usr/bin/perl + +# Adapted from: +# newrules.pl, Copyright (C) 2001 Justin R. Smith (jsmith@mcs.drexel.edu) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA +# 2003 Oct 11: Add -l option by Yuichi Nakamura(ynakam@users.sourceforge.jp) + + +$load_policy_pattern="avc:.*granted.*{.*load_policy.*}"; + +while ($opt = shift @ARGV) { + if ($opt eq "-d") { $read_dmesg++; } + elsif ($opt eq "-v") { $verbose++; } + elsif ($opt eq "-i") { $input = shift @ARGV; } + elsif ($opt eq "-o") { $output= shift @ARGV; } + elsif ($opt eq "-l") { $load_policy++; } + elsif ($opt eq "--help") { &printUsage; } + else { print "unknown option, '$opt'\n\n"; &printUsage; } +} + +if ($read_dmesg && $input) { + print "Error, can't read from both dmesg and $input\n\n"; + &printUsage; +} + +if ($read_dmesg) { open (IN, "/bin/dmesg|"); } +elsif ($input) { open (IN, "$input"); } +else { open (IN, "-"); } # STDIN + +if ($output) { open (OUT, ">>$output"); } +else { open (OUT, ">-"); } # STDOUT + +if($load_policy){ #store logs after last "load_policy" in @log_buf + while ($line = ) { + if($line=~/$load_policy_pattern/) { + #stored logs are unnecessary + undef @log_buf; + } + else + { + push @log_buf,$line; + } + } +} + +while ($line=&readNewline) { + next unless ($line =~ m/avc:\s*denied\s*\{((\w|\s)*)\}/); + @types=split /\ /,$line; + $info=""; + $group=""; + $command=""; + foreach $i(0..$#types){ + next if($types[$i]!~/[=\{]/); + if($types[$i]=~/^\{/){ + $j=$i+1; + while($types[$j]!~/\}/){ + $command.=" $types[$j]"; + $j++; + } + next; + } + my($a,$b) = split /=/,$types[$i]; + + next if($a eq "pid"); + next if($a eq "dev"); + next if($a eq "ino"); + + if(($a eq "scontext")||($a eq "tcontext")||($a eq "tclass")){ + if($a ne "tclass"){ + my($c,$c,$c) = split /:/, $b; + $b=$c; + } + $b=~s/\n//; + $group.="|$b"; + next; + } + $b=~s/:\[\d+\]//; + $a=uc $a; + $info.="$a=$b "; + } + + my($c,$c,$c,$c) = split /\|/, $group; + $info=~s/\ $c=\S+\ //gi; + # escape regexp patterns -- + $info=~s/([^\w])/\\$1/g; + + @atypes=split /\ /,$command; + foreach $i(0..$#atypes){ + $rules{$group}{$atypes[$i]}++; + } + + $info.=" "; + if($occur{$group}!~$info){ + $occur{$group}.="\t#$info: $command\n"; + } + else{ + my ($a,$b) = split /$info:\ /, $occur{$group}; + my ($temp) = split /\n/, $b; + + @com=split /\ /, $command; + foreach $i(1..$#com){ + $b=" $com[$i]$b" if($temp!~$com[$i]); + } + $occur{$group}="$a$info: $b"; + } +} + +# done with the input file +# now generate the rules +foreach $k (sort keys %rules) +{ + my ($a,$scontext,$tcontext,$tclass) = split /\|/, $k; + if ($scontext eq $tcontext) { + $tcontext = 'self'; + } + print OUT "allow $scontext $tcontext:$tclass"; + + my $access_types = $rules{$k}; + $len=(keys %$access_types); + if ($len gt 2 ) { print OUT " {"; } + foreach $t (sort keys %$access_types) { + if ($t ne "") {print OUT " $t";} + } + if ($len gt 2 ) { print OUT " }"; } + print OUT ";\n"; + $occur{$k} =~ s/\\(.)/$1/g; # de-escape string + print OUT "$occur{$k}\n" if ($verbose); +} + +exit; + +sub readNewline { + if($load_policy){ + $newline=shift @log_buf; + }else{ + $newline=; + } + return $newline; +} + +sub printUsage { + print "audit2allow [-d] [-v] [-l] [-i ] [-o ] + -d read input from output of /bin/dmesg + -v verbose output + -l read input only after last \"load_policy\" + -i read input from + -o append output to \n"; + exit; +} + diff --exclude-from=exclude -N -u -r nsapolicycoreutils/scripts/genhomedircon policycoreutils-1.27.28/scripts/genhomedircon --- nsapolicycoreutils/scripts/genhomedircon 2005-11-16 15:27:46.000000000 -0500 +++ policycoreutils-1.27.28/scripts/genhomedircon 2005-11-16 23:21:23.000000000 -0500 @@ -29,7 +29,9 @@ import commands, sys, os, pwd, string, getopt, re from semanage import *; -EXCLUDE_LOGINS=["/sbin/nologin", "/bin/false"] +fd=open("/etc/shells", 'r') +VALID_SHELLS=fd.read().split('\n') +fd.close() def getStartingUID(): starting_uid = sys.maxint @@ -63,12 +65,7 @@ homedir = homedir.strip() if not homedir in ret: ret.append(homedir) - else: - #rc[0] == 256 means the file was there, we read it, but the grep didn't match - if rc[0] != 256: - sys.stderr.write("%s\n" % rc[1]) - sys.stderr.write("You do not have access to /etc/default/useradd HOME=\n") - sys.stderr.flush() + rc=commands.getstatusoutput("grep -h '^LU_HOMEDIRECTORY' /etc/libuser.conf") if rc[0] == 0: homedir = rc[1].split("=")[1] @@ -76,12 +73,7 @@ homedir = homedir.strip() if not homedir in ret: ret.append(homedir) - else: - #rc[0] == 256 means the file was there, we read it, but the grep didn't match - if rc[0] != 256: - sys.stderr.write("%s\n" % rc[1]) - sys.stderr.write("You do not have access to /etc/libuser.conf LU_HOMEDIRECTORY=\n") - sys.stderr.flush() + if ret == []: ret.append("/home") return ret @@ -240,9 +232,8 @@ if rc[0] == 0: prefix_regex = rc[1].split("\n") else: - sys.stderr.write("%s\n" % rc[1]) - sys.stderr.write("You do not have access to grep/cut/the file contexts\n") - sys.stderr.flush() + warning("%s\nYou do not have access to read %s\n" % (rc[1], self.getFileContectFile())) + exists=1 for regex in prefix_regex: #match a trailing (/*)? which is actually a bug in rpc_pipefs @@ -272,7 +263,7 @@ ulist = pwd.getpwall() for u in ulist: if u[2] >= starting_uid and \ - not u[6] in EXCLUDE_LOGINS and \ + u[6] in VALID_SHELLS and \ u[5] != "/" and \ string.count(u[5], "/") > 1: homedir = u[5][:string.rfind(u[5], "/")]