audit-parse.pl 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use DBI;
  4. use POSIX qw(locale_h);
  5. # global database variables
  6. my ($dbh, $query, $sth, $par, $udh);
  7. sub readconfig($) {
  8. my ($fn) = @_;
  9. my %options;
  10. open(CFG, $fn) or die("unable to open ".$fn." config file");
  11. while (<CFG>) {
  12. if ($_ =~ /^\s*[#!]/) {
  13. next;
  14. }
  15. if ($_ =~ /^\s*(\S+)\s*=\s*([^\r]+)\r?$/) {
  16. my $idx = $1;
  17. my $val = $2;
  18. chomp($val);
  19. $val =~ s/\s+$//;
  20. $options{$idx} = $val;
  21. }
  22. }
  23. close(CFG);
  24. return %options;
  25. }
  26. sub databasename($$) {
  27. my ($id, $type) = @_;
  28. my @row;
  29. my $tag = 0x3001; # PR_DISPLAY_NAME
  30. if ($type == 5) {
  31. $tag = 0x37; # PR_SUBJECT
  32. }
  33. $sth->execute($tag, $id);
  34. @row = $sth->fetchrow_array();
  35. if (@row && defined($row[0])) {
  36. return $row[0];
  37. } else {
  38. if ($type == 1) {
  39. return "store";
  40. } else {
  41. return "$id";
  42. }
  43. }
  44. }
  45. sub databasename_tree($$) {
  46. my ($id, $type) = @_;
  47. my @tree;
  48. my @row = ($id,$type);
  49. while (@row) {
  50. push(@tree, databasename($id, $type));
  51. $par->execute($id);
  52. @row = $par->fetchrow_array();
  53. if (@row) {
  54. if (defined($row[0])) {
  55. $id = $row[0];
  56. $type = $row[1];
  57. } else {
  58. last;
  59. }
  60. }
  61. }
  62. return "'".join("\\", reverse(@tree))."'";
  63. }
  64. sub mapitype($) {
  65. my ($type) = @_;
  66. # only store, folder and message will actually happen
  67. if ($type eq 1) {
  68. return "'store'";
  69. } elsif ($type eq 2) {
  70. return "'addrbook'";
  71. } elsif ($type eq 3) {
  72. return "'folder'";
  73. } elsif ($type eq 4) {
  74. return "'abcont'";
  75. } elsif ($type eq 5) {
  76. return "'message'";
  77. } elsif ($type eq 6) {
  78. return "'mailuser'";
  79. } elsif ($type eq 7) {
  80. return "'attach'";
  81. } elsif ($type eq 8) {
  82. return "'distlist'";
  83. } elsif ($type eq 9) {
  84. return "'profsect'";
  85. } elsif ($type eq 10) {
  86. return "'status'";
  87. } elsif ($type eq 11) {
  88. return "'session'";
  89. } elsif ($type eq 12) {
  90. return "'forminfo'";
  91. }
  92. return "'unknown'";
  93. }
  94. sub parse_entry($) {
  95. my ($input) = @_;
  96. my $output = $input;
  97. my %values = ();
  98. if ($input =~ m/access (\S+) (.*)/) {
  99. my @options = split(/ /,$2);
  100. foreach(@options) {
  101. my @c = split(/=/,$_);
  102. $values{$c[0]} = $c[1];
  103. }
  104. if (keys(%values) > 0) {
  105. $values{objectid} = databasename_tree($values{objectid}, $values{type});
  106. $values{type} = mapitype($values{type});
  107. @options = ();
  108. foreach(keys(%values)) {
  109. push(@options, $_."=".$values{$_});
  110. }
  111. }
  112. $output = "access $1 ".join(" ", @options);
  113. }
  114. return $output;
  115. }
  116. #### main ####
  117. setlocale(LC_CTYPE, "");
  118. my $servercfg = $ARGV[0];
  119. $servercfg = "/etc/kopano/server.cfg" if (!defined($servercfg));
  120. my %serveropt = readconfig($servercfg);
  121. $dbh = DBI->connect("dbi:mysql:database=".$serveropt{mysql_database}.";host=".$serveropt{mysql_host}, $serveropt{mysql_user}, $serveropt{mysql_password})
  122. or die "Database error: ".$DBI::errstr;
  123. $dbh->do("set character_set_client = 'utf8'")
  124. or die "Database error: ".$DBI::errstr;
  125. $dbh->do("set character_set_connection = 'utf8'")
  126. or die "Database error: ".$DBI::errstr;
  127. $dbh->do("set character_set_results = 'utf8'")
  128. or die "Database error: ".$DBI::errstr;
  129. $query = "SELECT val_string FROM properties WHERE type=0x1e and tag=? and hierarchyid=?";
  130. $sth = $dbh->prepare($query)
  131. or die "Database error: ".$DBI::errstr;
  132. $query = "select ph.id as pid, ph.type as ptype from hierarchy as ph join hierarchy on ph.id=hierarchy.parent where hierarchy.id=?";
  133. $par = $dbh->prepare($query)
  134. or die "Database error: ".$DBI::errstr;
  135. while (<STDIN>) {
  136. # syslog
  137. # Feb 28 11:17:21 <hostname> kopano-server[5307]: server startup by user uid=1000
  138. # Feb 28 17:53:35 <hostname> kopano-server[5311]: authenticate ok user='jdoe' from='file:///var/run/kopano/server.sock' method='Pipe socket' program='kopano-dagent'
  139. # Feb 28 13:07:04 <hostname> kopano-server[5311]: access allowed objectid=991 type=3 ownername='constant' username='jdoe' rights='view'
  140. # ...
  141. # logfile
  142. # di 01 mrt 2011 09:48:29 CET: server startup by user uid=1000
  143. my $fixup;
  144. if ($_ =~ m/(.*) (kopano-server\[\d+\]): (.*)/) { # syslog
  145. $fixup = parse_entry($3);
  146. print "$1 $2: $fixup\n";
  147. } elsif ($_ =~ /(.*): (.*)/) { # too generic?
  148. $fixup = parse_entry($2);
  149. print "$1: $fixup\n";
  150. }
  151. }