--- ServerTACACSPLUS.pm 2013-03-14 15:51:32.917406943 +0100
+++ ServerTACACSPLUS_RemoteInContext.pm 2013-03-14 16:58:07.369471418 +0100
@@ -115,6 +115,9 @@
  'SingleSession' => 
  ['flag', 'Tells the server to try to maintain a single session for all TACACS+ request from the same client', 1],
 
+ 'RemoteInContext' => 
+ ['flag', 'Tells the server to use also the Remote address to maintain the context', 1],
+
  'PacketTrace'                 => 
  ['flag', 
   'Forces all packets that pass through this module to be logged at trace level 4. This is useful for logging packets that pass through this clause in more detail than other clauses during testing or debugging. The packet tracing  will stay in effect until it passes through another clause with PacketTrace set to off or 0.', 
@@ -205,6 +208,7 @@
     $self->{UsernamePrompt} = 'Username: ';
     $self->{PasswordPrompt} = 'Password: ';
     $self->{SingleSession} = 1;
+    $self->{RemoteInContext} = 0;
 }
 
 #####################################################################
@@ -238,6 +242,7 @@
         AuthenticationStartHook   => $self->{AuthenticationStartHook},
         AuthenticationContinueHook=> $self->{AuthenticationContinueHook},
         SingleSession             => $self->{SingleSession},
+        RemoteInContext           => $self->{RemoteInContext},
         );
 }
 
@@ -518,6 +523,8 @@
     $self->{port} = $port;
     $self->{service} = $service;
     $self->{rem_addr} = $rem_addr;
+
+
     my $tp = $self->create_radius_request('Access-Request');
     $tp->add_attr('cisco-avpair', "action=$action");
     $tp->add_attr('cisco-avpair', "authen_type=$authen_type");
@@ -826,8 +833,11 @@
     $self->{port} = $port;
     $self->{rem_addr} = $rem_addr;
 
+    my $context_id = "$self->{user}:$self->{peeraddr}";
+    $context_id .= ":$self->{rem_addr}" if  $self->{RemoteInContext};
+
     # Recover the context and any radius reply to our earlier authentication request
-    my $context = &Radius::Context::find("tacacs:$self->{user}:$self->{peeraddr}");
+    my $context = &Radius::Context::find("tacacs:$context_id");
     if (!$context)
     {
        # No context, so not authorised, reject
@@ -850,18 +860,19 @@
     # if the AuthGroupAttr is set either set the user/group pair
     # in the cache file or retrieve it if the timeout has expired.
     my $group_name = 'DEFAULT';
+
     if ($rp && $group_name_attr) 
     {
        my $g = $rp->get_attr($group_name_attr);
        if (defined $g)
        {
            $group_name = $g;
-           $self->authgroup_file("set", "$user:$self->{peeraddr}", $g);
+           $self->authgroup_file("set", $context_id, $g);
        }
     }
     elsif ($group_name_attr) 
     { 
-       my $g = $self->authgroup_file("get", "$user:$self->{peeraddr}");
+       my $g = $self->authgroup_file("get", $context_id );
        $group_name = $g if defined $g;
     }
 
@@ -1148,7 +1159,11 @@
        # for the authorisation phase. Therefore we cant cache the reply in $self.
        # So we have to create a context to hold the reply for a few seconds until
        # (maybe) an authorization REQUEST for this user arrives.
-       my $context = Radius::Context::get("tacacs:$self->{user}:$self->{peeraddr}", $self->{AuthorizationTimeout});
+
+       my $context_id = "$self->{user}:$self->{peeraddr}";
+       $context_id .= ":$self->{rem_addr}" if  $self->{RemoteInContext};
+
+       my $context = Radius::Context::get("tacacs:$context_id", $self->{AuthorizationTimeout});
        $context->{rp} = $tp->{rp};
 
        # If the reply contains any attributes named by AuthorizeGroupAttr, get