andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From d21d33e084ceae4d8cd8f1585852cb1f40b16d09 Mon Sep 17 00:00:00 2001
dc8c34
From: Mark Reynolds <mareynol@redhat.com>
dc8c34
Date: Wed, 9 May 2012 12:17:57 -0400
dc8c34
Subject: [PATCH 121/225] Ticket #356 - RFE - Track bind info
dc8c34
dc8c34
Bug Description:  Have a way to gather bind stats (operations and IP addresses).
dc8c34
dc8c34
Fix Description:  Added a new option "-B,--bind" which takes one of three arguemnts:
dc8c34
                   [1]  ALL - report on all Bind DN's
dc8c34
                   [2]  ANONYMOUS - report just on anonymous binds
dc8c34
                   [3]  "Bind DN" - report on the specified bind dn (uid=mark,dc=example,dc=com)
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/356
dc8c34
dc8c34
reviewed by:
dc8c34
(cherry picked from commit 9918105f615084f65a47fad693e02fce53bb7d72)
dc8c34
(cherry picked from commit 4ce70fed8dba0db072d4f7e4c8203f4e754352d1)
dc8c34
---
dc8c34
 ldap/admin/src/logconv.pl | 263 ++++++++++++++++++++++++++++++++++++++++++++--
dc8c34
 1 file changed, 252 insertions(+), 11 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
dc8c34
index 3f73bb7..94ba036 100755
dc8c34
--- a/ldap/admin/src/logconv.pl
dc8c34
+++ b/ldap/admin/src/logconv.pl
dc8c34
@@ -63,7 +63,7 @@ if ($#ARGV < 0){;
dc8c34
 $x = "0";
dc8c34
 $fc = 0;
dc8c34
 $sn = 0;
dc8c34
-$logversion = "6.1";
dc8c34
+$logversion = "6.11";
dc8c34
 $sizeCount = "20";
dc8c34
 $startFlag = 0;
dc8c34
 $startTime = 0;
dc8c34
@@ -80,6 +80,7 @@ GetOptions(
dc8c34
 	's|sizeLimit=s' => \$sizeCount,
dc8c34
 	'S|startTime=s' => \$startTime,
dc8c34
 	'E|endTime=s' => \$endTime,
dc8c34
+	'B|bind=s' => sub { $reportBinds = "yes"; $bindReportDN=($_[1]) },
dc8c34
 	'm|reportFileSecs=s' => sub { my ($opt,$value) = @_; $s_stats = new_stats_block($value); },
dc8c34
 	'M|reportFileMins=s' =>  sub { my ($opt,$value) = @_; $m_stats = new_stats_block($value); },
dc8c34
 	'h|help' => sub { displayUsage() },
dc8c34
@@ -103,6 +104,19 @@ GetOptions(
dc8c34
 );
dc8c34
 
dc8c34
 #
dc8c34
+# setup the report Bind DN if any
dc8c34
+#
dc8c34
+if($reportBinds eq "yes"){
dc8c34
+	$bindReportDN =~ tr/A-Z/a-z/;
dc8c34
+	if($bindReportDN eq "all"){
dc8c34
+		$bindReportDN = "";
dc8c34
+	}
dc8c34
+	if($bindReportDN eq "anonymous"){
dc8c34
+		$bindReportDN = "Anonymous";
dc8c34
+	}
dc8c34
+}
dc8c34
+
dc8c34
+#
dc8c34
 # set the default root DN
dc8c34
 #
dc8c34
 if($manager eq ""){
dc8c34
@@ -490,13 +504,26 @@ $elapsedSeconds = $remainingTimeInSecs;
dc8c34
 
dc8c34
 
dc8c34
 print "\n\n----------- Access Log Output ------------\n";
dc8c34
-print "\nStart of Log:    $start\n";
dc8c34
-print "End of Log:      $end\n\n";
dc8c34
+print "\nStart of Logs:    $start\n";
dc8c34
+print "End of Logs:      $end\n\n";
dc8c34
 if($elapsedDays eq "0"){
dc8c34
         print "Processed Log Time:  $elapsedHours Hours, $elapsedMinutes Minutes, $elapsedSeconds Seconds\n\n";
dc8c34
 } else {
dc8c34
         print "Processed Log Time:  $elapsedDays Days, $elapsedHours Hours, $elapsedMinutes Minutes, $elapsedSeconds Seconds\n\n";
dc8c34
 }
dc8c34
+
dc8c34
+#
dc8c34
+#  Check here if we are producing any unqiue reports
dc8c34
+#
dc8c34
+
dc8c34
+if($reportBinds eq "yes"){
dc8c34
+	&displayBindReport();
dc8c34
+}
dc8c34
+
dc8c34
+#
dc8c34
+# Continue with standard report
dc8c34
+#
dc8c34
+
dc8c34
 print "Restarts:                     $restarts\n";
dc8c34
 print "Total Connections:            $connectionCount\n";
dc8c34
 print "SSL Connections:              $sslconn\n";
dc8c34
@@ -1198,7 +1225,8 @@ sub displayUsage {
dc8c34
 	print "             E.g. \"[28/Mar/2002:13:24:62 -0800]\"\n";
dc8c34
 	print "         -m, --reportFileSecs  <CSV output file - per second stats>\n"; 
dc8c34
 	print "         -M, --reportFileMins  <CSV output file - per minute stats>\n";	
dc8c34
-	print "         -V, --verbose         <enable verbose output - includes all stats listed below>\n";
dc8c34
+	print "         -B, --bind         <ALL | ANONYMOUS | \"Actual Bind DN\">\n";
dc8c34
+	print "         -V, --verbose      <enable verbose output - includes all stats listed below>\n";
dc8c34
 	print "         -[efcibaltnxrgjuyp]\n\n";
dc8c34
 
dc8c34
 	print "                 e       Error Code stats\n";
dc8c34
@@ -1221,24 +1249,162 @@ sub displayUsage {
dc8c34
 	print "  Examples:\n\n";
dc8c34
 
dc8c34
 	print "         ./logconv.pl -s 10 -V /logs/access*\n\n";
dc8c34
-
dc8c34
 	print "         ./logconv.pl --rootDN cn=dm /logs/access*\n\n";
dc8c34
-
dc8c34
 	print "         ./logconv.pl --sizeLimit 50 -ibgju /logs/access*\n\n";
dc8c34
-
dc8c34
 	print "         ./logconv.pl -S \"\[28/Mar/2002:13:14:22 -0800\]\" --endTime \"\[28/Mar/2002:13:50:05 -0800\]\" -e /logs/access*\n\n";
dc8c34
 	print "         ./logconv.pl -m log-minute-stats-csv.out /logs/access*\n\n";
dc8c34
+	print "         ./logconv.pl -B ANONYMOUS /logs/access*\n\n";
dc8c34
+	print "         ./logconv.pl -B \"uid=mreynolds,dc=example,dc=com\" /logs/access*\n\n";
dc8c34
 
dc8c34
 	exit 1;
dc8c34
 }
dc8c34
 
dc8c34
 ######################################################
dc8c34
 #
dc8c34
-# Parsing Routine That Does The Actual Parsing Work
dc8c34
+# Parsing Routines That Do The Actual Parsing Work
dc8c34
 #
dc8c34
 ######################################################
dc8c34
 
dc8c34
-sub parseLine {
dc8c34
+sub
dc8c34
+parseLine {
dc8c34
+	if($reportBinds eq "yes"){
dc8c34
+		&parseLineBind();		
dc8c34
+	} else {
dc8c34
+		&parseLineNormal();
dc8c34
+	}
dc8c34
+}
dc8c34
+
dc8c34
+sub
dc8c34
+parseLineBind {
dc8c34
+	$ff++;
dc8c34
+	$iff++;
dc8c34
+	local $_ = $tline;
dc8c34
+
dc8c34
+	if ($iff >= $limit){
dc8c34
+		print STDERR sprintf" %10s Lines Processed\n",$ff;
dc8c34
+		$iff="0";
dc8c34
+	}
dc8c34
+
dc8c34
+	# skip blank lines
dc8c34
+	return if $_ =~ /^\s/;
dc8c34
+
dc8c34
+	if($firstFile eq "1" && $_ =~ /^\[/){
dc8c34
+        	$start = $_;
dc8c34
+        	if ($start =~ / *([0-9a-z:\/]+)/i){$start=$1;}
dc8c34
+        		$firstFile = "0";
dc8c34
+	}
dc8c34
+
dc8c34
+	if ($endFlag != 1 && $_ =~ /^\[/ && $_ =~ / *([0-9a-z:\/]+)/i){
dc8c34
+		$end =$1;
dc8c34
+	}
dc8c34
+
dc8c34
+	if ($startTime && !$startFlag) {
dc8c34
+        	if (index($_, $startTime) == 0) {
dc8c34
+                	$startFlag = 1;
dc8c34
+                	($start) = $startTime =~ /\D*(\S*)/;
dc8c34
+        	} else {
dc8c34
+                	return;
dc8c34
+        	}
dc8c34
+	}
dc8c34
+
dc8c34
+	if ($endTime && !$endFlag) {
dc8c34
+        	if (index($_, $endTime) == 0) {
dc8c34
+                	$endFlag = 1;
dc8c34
+                	($end) = $endTime =~ /\D*(\S*)/;
dc8c34
+        	}
dc8c34
+	}
dc8c34
+
dc8c34
+	if ($_ =~ /connection from *([0-9A-Fa-f\.\:]+)/i ) {
dc8c34
+		for ($excl =0; $excl <= $#exclude; $excl++){
dc8c34
+			if ($exclude[$excl] eq $1){
dc8c34
+				$skip = "yes";
dc8c34
+				last;
dc8c34
+			}
dc8c34
+                }
dc8c34
+                if ($skip eq "yes"){
dc8c34
+			return ;
dc8c34
+		}
dc8c34
+		$ip = $1;
dc8c34
+		if ($_ =~ /conn= *([0-9]+)/i ){
dc8c34
+			$connList{$ip} = $connList{$ip} . " $1 ";
dc8c34
+		}
dc8c34
+		return;
dc8c34
+	}
dc8c34
+
dc8c34
+ 	if (/ BIND/ && $_ =~ /dn=\"(.*)\" method/i ){
dc8c34
+        	if ($1 eq ""){
dc8c34
+			$dn = "Anonymous";
dc8c34
+		} else {
dc8c34
+			$dn = $1;
dc8c34
+			$dn =~ tr/A-Z/a-z/;
dc8c34
+		}
dc8c34
+
dc8c34
+		if($bindReportDN ne ""){
dc8c34
+			if($dn ne $bindReportDN){
dc8c34
+				#  We are not looking for this DN, skip it
dc8c34
+				return;
dc8c34
+			}
dc8c34
+		}
dc8c34
+
dc8c34
+		$bindReport{$dn}{"binds"}++;
dc8c34
+        	if ($bindReport{$dn}{"binds"} eq 1){
dc8c34
+			# For hashes we need to init the counters
dc8c34
+			$bindReport{$dn}{"srch"} = 0;
dc8c34
+			$bindReport{$dn}{"add"} = 0;
dc8c34
+			$bindReport{$dn}{"mod"} = 0;
dc8c34
+			$bindReport{$dn}{"del"} = 0;
dc8c34
+			$bindReport{$dn}{"cmp"} = 0;
dc8c34
+			$bindReport{$dn}{"ext"} = 0;
dc8c34
+			$bindReport{$dn}{"modrdn"} = 0;
dc8c34
+			$bindReport{$dn}{"failedBind"} = 0;
dc8c34
+		}
dc8c34
+
dc8c34
+		if ($_ =~ /conn= *([0-9]+)/i) {
dc8c34
+			$bindReport{$dn}{"conn"} = $bindReport{$dn}{"conn"} . " $1 ";
dc8c34
+		}
dc8c34
+		return;
dc8c34
+ 	}
dc8c34
+
dc8c34
+	if (/ RESULT err=49 /){
dc8c34
+		processOpForBindReport("failedBind",$tline);
dc8c34
+	}
dc8c34
+
dc8c34
+	if (/ SRCH base=/){
dc8c34
+		processOpForBindReport("srch",$tline);
dc8c34
+	} elsif (/ ADD dn=/){
dc8c34
+		processOpForBindReport("add",$tline);
dc8c34
+	} elsif (/ MOD dn=/){
dc8c34
+		processOpForBindReport("mod",$tline);
dc8c34
+	} elsif (/ DEL dn=/){                
dc8c34
+		processOpForBindReport("del",$tline);
dc8c34
+	} elsif (/ MODRDN dn=/){
dc8c34
+		processOpForBindReport("modrdn",$tline);
dc8c34
+	} elsif (/ CMP dn=/){
dc8c34
+		processOpForBindReport("cmp",$tline);
dc8c34
+	} elsif (/ EXT oid=/){
dc8c34
+		processOpForBindReport("ext",$tline);
dc8c34
+	} 
dc8c34
+
dc8c34
+}
dc8c34
+
dc8c34
+sub
dc8c34
+processOpForBindReport
dc8c34
+{
dc8c34
+	$op = @_[0];
dc8c34
+	$data = @_[1];
dc8c34
+
dc8c34
+	if ($data =~ /conn= *([0-9]+)/i) {
dc8c34
+		foreach $dn (keys %bindReport){
dc8c34
+			if ($bindReport{$dn}{"conn"} =~ / $1 /){
dc8c34
+				$bindDN = $dn;
dc8c34
+				$bindReport{$bindDN}{$op}++;
dc8c34
+				return;
dc8c34
+			}
dc8c34
+		}
dc8c34
+	}
dc8c34
+}
dc8c34
+
dc8c34
+sub parseLineNormal {
dc8c34
 local $_ = $tline;
dc8c34
 
dc8c34
 # lines starting blank are restart
dc8c34
@@ -1410,7 +1576,7 @@ if (m/ conn=1 fd=/){$restarts++}
dc8c34
 if (m/ SSL connection from/){$sslconn++;}
dc8c34
 if (m/ connection from/){
dc8c34
      $exc = "no";
dc8c34
-     if ($_ =~ /connection from *([0-9\.]+)/i ){ 
dc8c34
+     if ($_ =~ /connection from *([0-9A-Fa-f\.\:]+)/i ){ 
dc8c34
 	for ($xxx =0; $xxx <= $#exclude; $xxx++){
dc8c34
 		if ($exclude[$xxx] eq $1){$exc = "yes";}
dc8c34
 	}
dc8c34
@@ -1561,7 +1727,7 @@ if ($usage =~ /g/ || $usage =~ /c/ || $usage =~ /i/ || $verb eq "yes"){
dc8c34
 
dc8c34
 $exc = "no";
dc8c34
 
dc8c34
-if ($_ =~ /connection from *([0-9\.]+)/i ) {
dc8c34
+if ($_ =~ /connection from *([0-9A-fa-f\.\:]+)/i ) {
dc8c34
 	for ($xxx = 0; $xxx <= $#exclude; $xxx++){
dc8c34
 		if ($1 eq $exclude[$xxx]){
dc8c34
 			$exc = "yes";
dc8c34
@@ -2017,6 +2183,81 @@ inc_stats
dc8c34
     return;
dc8c34
 }
dc8c34
 
dc8c34
+sub
dc8c34
+displayBindReport
dc8c34
+{
dc8c34
+    #
dc8c34
+    #  Loop for each DN - sort alphabetically
dc8c34
+    #
dc8c34
+    #  Display all the IP addresses, then counts of all the operations it did
dc8c34
+    #
dc8c34
+
dc8c34
+    print "\nBind Report\n";
dc8c34
+    print "====================================================================\n\n";
dc8c34
+    foreach $bindDN (sort { $bindReport{$a} <=> $bindReport{$b} } keys %bindReport) {
dc8c34
+        print("Bind DN: $bindDN\n");
dc8c34
+        print("--------------------------------------------------------------------\n");
dc8c34
+        print("   Client Addresses:\n\n");
dc8c34
+        &printClients($bindReport{$bindDN}{"conn"});
dc8c34
+        print("\n   Operations Performed:\n\n");
dc8c34
+        &printOpStats($bindDN);
dc8c34
+        print("\n");	
dc8c34
+    }
dc8c34
+    print "Done.\n";
dc8c34
+    exit (0);
dc8c34
+}
dc8c34
+
dc8c34
+sub
dc8c34
+printClients
dc8c34
+{ 
dc8c34
+    @bindConns = &cleanConns(split(' ', @_[0]));
dc8c34
+    $IPcount = "1";
dc8c34
+
dc8c34
+    foreach $ip ( keys %connList ){   # Loop over all the IP addresses
dc8c34
+        foreach $bc (@bindConns){ # Loop over each bind conn number and compare it 
dc8c34
+	    if($connList{$ip} =~ / $bc /){ 
dc8c34
+                print("        [$IPcount]  $ip\n");
dc8c34
+                $IPcount++;
dc8c34
+                last;
dc8c34
+            }
dc8c34
+        }
dc8c34
+    }
dc8c34
+}
dc8c34
+
dc8c34
+sub
dc8c34
+cleanConns
dc8c34
+{
dc8c34
+    @dirtyConns = @_;
dc8c34
+    $#cleanConns = -1;
dc8c34
+    $c = 0;
dc8c34
+
dc8c34
+    for ($i = 0; $i <=$#dirtyConns; $i++){
dc8c34
+        if($dirtyConns[$i] ne ""){
dc8c34
+            $cleanConns[$c++] = $dirtyConns[$i];
dc8c34
+        }
dc8c34
+    }	
dc8c34
+    return @cleanConns;
dc8c34
+}
dc8c34
+
dc8c34
+sub
dc8c34
+printOpStats
dc8c34
+{
dc8c34
+    $dn = @_[0];
dc8c34
+
dc8c34
+    if( $bindReport{$dn}{"failedBind"} eq "0" ){
dc8c34
+        print("        Binds:        " . $bindReport{$dn}{"binds"} . "\n");
dc8c34
+    } else {
dc8c34
+        print("        Binds:        " . $bindReport{$dn}{"binds"} . "  (Invalid Credentials: " . $bindReport{$dn}{"failedBind"} . ")\n");
dc8c34
+    }
dc8c34
+    print("        Searches:     " . $bindReport{$dn}{"srch"} . "\n");
dc8c34
+    print("        Modifies:     " . $bindReport{$dn}{"mod"} . "\n");
dc8c34
+    print("        Adds:         " . $bindReport{$dn}{"add"} . "\n");
dc8c34
+    print("        Deletes:      " . $bindReport{$dn}{"del"} . "\n");
dc8c34
+    print("        Compares:     " . $bindReport{$dn}{"cmp"} . "\n");
dc8c34
+    print("        ModRDNs:      " . $bindReport{$dn}{"modrdn"} . "\n");
dc8c34
+    print("        Ext Ops:      " . $bindReport{$dn}{"ext"} . "\n\n");
dc8c34
+}
dc8c34
+
dc8c34
 #######################################
dc8c34
 #                                     #
dc8c34
 #             The  End                #
dc8c34
-- 
dc8c34
1.8.1.4
dc8c34