+=item sqlradius_user_disconnect
+
+For a specified user, sends a disconnect request to all nas in the server database.
+
+Accepts L</sqlradius_connect> connection input and the following named parameters:
+
+I<disconnect_ssh> - user@host with access to radclient program (required)
+
+I<svc_acct_username> - the user to be disconnected (required)
+
+I<disconnect_port> - the port (on the nas) to send disconnect requests to (defaults to 1700)
+
+Note this is NOT the opposite of sqlradius_connect.
+
+=cut
+
+sub sqlradius_user_disconnect {
+
+ if ( $FS::svc_Common::noexport_hack ) {
+ carp 'sqlradius_user_disconnect() suppressed by noexport_hack' if $DEBUG;
+ return;
+ }
+
+ my $dbh = sqlradius_connect(shift, shift, shift);
+ my %opt = @_;
+ # get list of nas
+ my $sth = $dbh->prepare('select nasname, secret from nas') or die $dbh->errstr;
+ $sth->execute() or die $dbh->errstr;
+ my $nas = $sth->fetchall_arrayref({});
+ $sth->finish();
+ $dbh->disconnect();
+ die "No nas found in radius db" unless @$nas;
+ # set up ssh connection
+ my $ssh = Net::OpenSSH->new($opt{'disconnect_ssh'});
+ die "Couldn't establish SSH connection: " . $ssh->error
+ if $ssh->error;
+ # send individual disconnect requests
+ my $user = $opt{'svc_acct_username'}; #svc_acct username
+ my $port = $opt{'disconnect_port'} || 1700; #or should we pull this from the db?
+ my $error = '';
+ foreach my $nas (@$nas) {
+ my $nasname = $nas->{'nasname'};
+ my $secret = $nas->{'secret'};
+ my $command = qq(echo "User-Name=$user" | radclient -r 1 $nasname:$port disconnect '$secret');
+ my ($output, $errput) = $ssh->capture2($command);
+ $error .= "Error running $command: $errput " . $ssh->error . " "
+ if $errput || $ssh->error;
+ }
+ $error .= "Some clients may have successfully disconnected"
+ if $error && (@$nas > 1);
+ $error = "No clients found"
+ unless @$nas;
+ die $error if $error;
+ return '';
+}
+