Hello.

I've found that checkrad script is using SNMP_Session perl module
that doesn't works correctly, so I would like to post little
patch for checkrad script to support Simultaneous-Use check with
l2tp LNS/NAS. You have to install Net::SNMP perl module to get
this thing working.

--- /usr/ports/net/freeradius/work/freeradius-1.0.2/src/main/checkrad.pl        
Thu Mar 17 06:00:31 2005
+++ checkrad    Fri Mar 18 16:50:06 2005
@@ -28,7 +28,7 @@
 #              netserver_telnet 1.0    Author: [EMAIL PROTECTED]
 #              versanet_snmp    1.0    Author: [EMAIL PROTECTED]
 #              bay_finger       1.0    Author: [EMAIL PROTECTED]
-#              cisco_l2tp       1.14   Author: [EMAIL PROTECTED]
+#              cisco_l2tp       0.1    Author: Volodya Vaynshteyn <[EMAIL 
PROTECTED]>
 #              mikrotik_telnet  1.1    Author: Evren Yurtesen <[EMAIL 
PROTECTED]>
 #              mikrotik_snmp    1.0    Author: Evren Yurtesen <[EMAIL 
PROTECTED]>
 #              redback_telnet          Author: Eduardo Roldan
@@ -43,6 +43,7 @@
 #              $naspass is the location of your NAS admin password file
 #
 
+
 $prefix                = "/usr/local";
 $localstatedir = "/var";
 $logdir                = "/var/log";
@@ -50,7 +51,7 @@
 $raddbdir      = "${sysconfdir}/raddb";
 
 $debug         = "";
-#$debug                = "$logdir/checkrad.log";
+$debug         = "$logdir/checkrad.log";
 
 $snmpget       = "/usr/local/bin/snmpget";
 $snmpwalk      = "/usr/local/bin/snmpwalk";
@@ -76,6 +77,7 @@
 #      Do not complain if we cannot find it.
 #      Prefer a locally installed copy.
 #
+
 BEGIN {
        unshift @INC, "/usr/local/lib/site_perl";
 
@@ -1114,47 +1116,89 @@
 # Make sure you set the $realm variable at the begining of the file if
 # needed. The new type for naslist is cisco_l2tp
 
-sub find_l2tp_login
-{
-  my($host, $community, $port_num) = @_;
-  my $l2tp_oid = '.1.3.6.1.4.1.9.10.24.1.3.2.1.2.2';
-  my $port_oid = 
'.iso.org.dod.internet.private.enterprises.9.10.51.1.2.1.1.2.2';
-  my $port = 'Vi' . $port_num;
-
-  my $sess = new SNMP::Session(DestHost => $host, Community =>  $community);
-  my $snmp_var = new  SNMP::Varbind(["$port_oid"]);
-  my $val = $sess->getnext($snmp_var);
-
-  do
-  {
-    $sess->getnext($snmp_var);
-  } until ($snmp_var->[$SNMP::Varbind::val_f] =~ /$port/) ||
-       (!($snmp_var->[$SNMP::Varbind::ref_f] =~ /^$port_oid\.(\d+)\.(\d+)$/)) 
||
-       ($sess->{ErrorNum});
-
-  my $val1 = $snmp_var->[$SNMP::Varbind::ref_f];
-
-  if ($val1 =~ /^$port_oid/) {
-    $result = substr($val1, length($port_oid));
-    $result =~ /^\.(\d+)\.(\d+)$/;
-    $tunID = $1;
-    $sessID = $2;
-  }
-
-  my $snmp_var1 = new SNMP::Varbind(["$l2tp_oid\.$tunID\.$sessID"]);
-  $val = $sess->get($snmp_var1);
-  my $login = $snmp_var1->[$SNMP::Varbind::val_f];
-
-  return $login;
-}
-
-sub cisco_l2tp_snmp
-{
-  my $login = find_l2tp_login("$ARGV[1]", $cmmty_string, "$ARGV[2]");
-  print LOG "  user at port S$ARGV[2]: $login\n" if ($debug);
-  ($login eq "[EMAIL PROTECTED]") ? 1 : 0;
+
+sub 
+cisco_l2tp_snmp {
+
+use Net::SNMP qw(oid_lex_sort oid_base_match SNMP_VERSION_1 DEBUG_ALL);
+
+       my ($nas_ip,$user)  = @_;
+        my ($method, $community) = naspasswd($nas_ip, 1);
+
+        if ($method eq '') {
+                $community = $cmmty_string;
+        } elsif ($method ne 'SNMP') {
+          print LOG "Error: Need SNMP community string for $nas_ip\n" if 
($debug);
+          return 2;
 }
 
+my ($s, $e) = Net::SNMP->session(
+        -hostname               => $nas_ip,
+        -community              => $community,
+        -version                => "2c",
+);
+
+ if (!defined($s)) {
+        print LOG $e if ($debug);
+        return 255;
+ } else {
+
+        use vars qw( %t_logname %t_port );
+
+       ## check cvpdnSessionAttrUserName
+        %t_logname = 
&get_table_as_hash($s,'.1.3.6.1.4.1.9.10.24.1.3.2.1.2.2.');
+        %t_port    = 
&get_table_as_hash($s,'.1.3.6.1.4.1.9.10.51.1.2.1.1.2.2.');
+
+        foreach $port_table_id (keys(%t_port)) {
+               if ($t_logname{$port_table_id} eq $user){ 
+                       print LOG "User $t_logname{$port_table_id} already 
logged in at port $t_port{$port_table_id}\n" if ($debug);
+                       return 1;
+               }
+        }
+       print LOG "User $user successfully logged in at port 
$t_port{$port_table_id}\n" if ($debug);
+       return 0;
+        $s->close();
+ }
+
+}
+
+sub
+get_table_as_hash() {
+
+        use vars qw( $num $val $oid %buf );
+        my ($s,$oid) = @_;
+
+        my @args = (
+                -varbindlist    => [$oid],
+                -maxrepetitions => 25,
+        );
+
+        outer: while (defined($s->get_bulk_request(@args))) {
+                my @oids = oid_lex_sort(keys(%{$s->var_bind_list}));
+                foreach (@oids) {
+                        if (!oid_base_match($oid, $_)) {
+                                last outer;
+                        }
+                        $num = $_;
+                        $num =~ s/$oid//;
+                        $val = $s->var_bind_list->{$_};
+                        $buf{$num} = $val;
+                        #printf("%s => %s\n", $num, $val);
+                        if ($s->var_bind_list->{$_} eq 'endOfMibView') {
+                                last outer;
+                        }
+                }
+        # Get the last OBJECT IDENTIFIER in the returned list
+                @args = (-maxrepetitions => 25, -varbindlist => [pop(@oids)]);
+        }
+        # Let the user know about any errors
+        if ($s->error() ne '') {
+                print $s->error();
+        }
+        return %buf;
+}
+
+
 sub mikrotik_snmp {
 
   # Set SNMP version
@@ -1411,7 +1455,7 @@
 } elsif ($ARGV[0] eq 'bay') {
        $ret = &bay_finger;
 } elsif ($ARGV[0] eq 'cisco_l2tp'){
-        $ret = &cisco_l2tp_snmp;
+        $ret = &cisco_l2tp_snmp($ARGV[1],$ARGV[3]);
 } elsif ($ARGV[0] eq 'mikrotik'){
         $ret = &mikrotik_telnet;
 } elsif ($ARGV[0] eq 'mikrotik_snmp'){

Reply via email to