228 lines
7.8 KiB
Perl
Executable file
228 lines
7.8 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
#
|
|
# This code was forked from the LiveJournal project owned and operated
|
|
# by Live Journal, Inc. The code has been modified and expanded by
|
|
# Dreamwidth Studios, LLC. These files were originally licensed under
|
|
# the terms of the license supplied by Live Journal, Inc, which can
|
|
# currently be found at:
|
|
#
|
|
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
|
|
#
|
|
# In accordance with the original license, this code and all its
|
|
# modifications are provided under the GNU General Public License.
|
|
# A copy of that license can be found in the LICENSE file included as
|
|
# part of this distribution.
|
|
|
|
use strict;
|
|
use Getopt::Long;
|
|
|
|
# parse input options
|
|
my ( $list, $add, $modify, $banid, $status, $bandate, $banuntil, $banlength, $what, $value, $note );
|
|
exit 1
|
|
unless GetOptions(
|
|
'list' => \$list,
|
|
'add' => \$add,
|
|
'modify' => \$modify,
|
|
'banid=s' => \$banid,
|
|
'status=s' => \$status,
|
|
'bandate=s' => \$bandate,
|
|
'banuntil=s' => \$banuntil,
|
|
'banlength=s' => \$banlength,
|
|
'what=s' => \$what,
|
|
'value=s' => \$value,
|
|
'note=s' => \$note,
|
|
);
|
|
|
|
# did they give valid input?
|
|
my $an_opt = ( $what || $value || $status || $bandate || $banuntil || $banlength || $note );
|
|
unless (
|
|
(
|
|
$list && ( ( $banid && !$an_opt ) || ( !$banid && $an_opt ) )
|
|
|| ( $add && $what && $value )
|
|
|| ( $modify && $banid && $an_opt )
|
|
)
|
|
)
|
|
{
|
|
|
|
die "Usage: ljsysban.pl [opts]\n\n"
|
|
. " --list { <--banid=?> | or one of:\n"
|
|
. " [--what=? --status=? --bandate=datetime --banuntil=datetime\n"
|
|
. " --value=? --note=?]\n"
|
|
. " }\n\n"
|
|
. " --add <--what=? --value=?\n"
|
|
. " [--status=? --bandate=datetime { --banuntil=datetime | --banlength=duration } --note=?]>\n\n"
|
|
. " --modify <--banid=?>\n"
|
|
. " [--status=? --bandate=datetime { --banuntil=datetime |\n"
|
|
. " --banlength=duration } --value=? --note=?]\n\n"
|
|
. "datetime in format 'YYYY-MM-DD HH:MM:SS', duration in format 'N[dhms]' e.g. '5d' or '3h'.\n\n"
|
|
. "examples:\n"
|
|
. " ljsysban.pl --list --what=ip --value=127.0.0.1\n"
|
|
. " ljsysban.pl --add --what=email --value=test\@test.com --banuntil='2006-06-01 00:00:00' --note='test'\n"
|
|
. " ljsysban.pl --add --what=uniq --value=jd87fdnef8jf8jef --banlength=3d --note='3 day ban'\n\n";
|
|
}
|
|
|
|
# now load in the beast
|
|
BEGIN {
|
|
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
|
|
}
|
|
use LJ::Sysban;
|
|
my $dbh = LJ::get_db_writer();
|
|
|
|
# list bans
|
|
if ($list) {
|
|
my $where;
|
|
if ($banid) {
|
|
$where = "banid=" . $dbh->quote($banid);
|
|
}
|
|
else {
|
|
my @where = ();
|
|
push @where, ( "what=" . $dbh->quote($what) ) if $what;
|
|
push @where, ( "value=" . $dbh->quote($value) ) if $value;
|
|
push @where, ( "status=" . $dbh->quote($status) ) if $status;
|
|
push @where, ( "bandate=" . $dbh->quote($bandate) ) if $bandate;
|
|
push @where, ( "banuntil=" . $dbh->quote($banuntil) ) if $banuntil;
|
|
push @where, ( "note=" . $dbh->quote($note) ) if $note;
|
|
$where = join( " AND ", @where );
|
|
}
|
|
|
|
my $sth = $dbh->prepare("SELECT * FROM sysban WHERE $where ORDER BY bandate ASC");
|
|
$sth->execute;
|
|
my $ct;
|
|
while ( my $ban = $sth->fetchrow_hashref ) {
|
|
print "> banid: $ban->{'banid'}, status: $ban->{'status'}, ";
|
|
print "bandate: " . ( $ban->{'bandate'} ? $ban->{'bandate'} : "BOT" ) . ", ";
|
|
print "banuntil: " . ( $ban->{'banuntil'} ? $ban->{'banuntil'} : "EOT" ) . "\n";
|
|
print "> what: $ban->{'what'}, value: $ban->{'value'}\n";
|
|
print "> note: $ban->{'note'}\n" if $ban->{'note'};
|
|
print "\n";
|
|
$ct++;
|
|
}
|
|
print "\n\tNO MATCHES\n\n" unless $ct;
|
|
|
|
exit;
|
|
}
|
|
|
|
# verify ban length and convert to banuntil as necessary
|
|
if ($banlength) {
|
|
die "--banlength must be of format N[dmhs] such as 3d, 5h, 60m, 35s.\n"
|
|
unless $banlength =~ /^(\d+)([dhms])$/i;
|
|
my ( $num, $type ) = ( $1, lc $2 );
|
|
$banlength = "DATE_ADD(NOW(), INTERVAL $num "
|
|
. { 'd' => "DAY", 'h' => "HOUR", 'm' => "MINUTE", 's' => "SECOND" }->{$type} . ")";
|
|
$banuntil = $dbh->selectrow_array("SELECT $banlength");
|
|
die $dbh->errstr if $dbh->err;
|
|
}
|
|
|
|
# add new ban
|
|
if ($add) {
|
|
|
|
$status = ( $status eq 'expired' ? 'expired' : 'active' );
|
|
|
|
$dbh->do(
|
|
"INSERT INTO sysban (status, what, value, note, bandate, banuntil)"
|
|
. "VALUES (?, ?, ?, ?, "
|
|
. ( $bandate ? $dbh->quote($bandate) : 'NOW()' ) . ", "
|
|
. ( $banuntil ? $dbh->quote($banuntil) : 'NULL' ) . ")",
|
|
undef, $status, $what, $value, $note
|
|
);
|
|
die $dbh->errstr if $dbh->err;
|
|
my $insertid = $dbh->{'mysql_insertid'};
|
|
|
|
LJ::Sysban::ban_do( $what, $value, LJ::mysqldate_to_time($banuntil) );
|
|
|
|
# log in statushistory
|
|
LJ::statushistory_add( 0, 0, 'sysban_add',
|
|
"banid=$insertid; status=$status; "
|
|
. "bandate="
|
|
. ( $bandate || LJ::mysql_time() ) . "; "
|
|
. "banuntil="
|
|
. ( $banuntil || 'NULL' ) . "; "
|
|
. "what=$what; value=$value; "
|
|
. "note=$note;" );
|
|
|
|
print "CREATED: banid=$insertid\n";
|
|
exit;
|
|
}
|
|
|
|
# modify existing ban
|
|
if ($modify) {
|
|
|
|
# load selected ban
|
|
my $ban = $dbh->selectrow_hashref( "SELECT * FROM sysban WHERE banid=?", undef, $banid );
|
|
die $dbh->errstr if $dbh->err;
|
|
|
|
my @set = ();
|
|
|
|
# ip/uniq ban and we're going to change the value
|
|
if ( ( $value && $value ne $ban->{'value'} )
|
|
|| $banuntil && $banuntil ne $ban->{'banuntil'}
|
|
|| ( $status && $status ne $ban->{'status'} && $status eq 'expired' ) )
|
|
{
|
|
|
|
LJ::Sysban::ban_undo( $ban->{what}, $value || $ban->{value} );
|
|
}
|
|
|
|
# what - must have a value
|
|
if ( $what && $what ne $ban->{'what'} ) {
|
|
$ban->{'what'} = $what;
|
|
push @set, "what=" . $dbh->quote( $ban->{'what'} );
|
|
}
|
|
|
|
# ip/uniq ban and we are going to change the value
|
|
if ( ( $value && $value ne $ban->{'value'} )
|
|
|| $banuntil && $banuntil ne $ban->{'banuntil'}
|
|
|| ( $status && $status ne $ban->{'status'} && $status eq 'active' ) )
|
|
{
|
|
|
|
my $new_value = $value || $ban->{value};
|
|
my $new_banuntil = LJ::mysqldate_to_time( $banuntil || $ban->{banuntil} );
|
|
|
|
LJ::Sysban::ban_do( $ban->{what}, $new_value, $new_banuntil );
|
|
}
|
|
|
|
# value - must have a value
|
|
if ( $value && $value ne $ban->{'value'} ) {
|
|
$ban->{'value'} = $value;
|
|
push @set, "value=" . $dbh->quote( $ban->{'value'} );
|
|
}
|
|
|
|
# status - must have a value
|
|
if ( $status && $status ne $ban->{'status'} ) {
|
|
$ban->{'status'} = ( $status eq 'expired' ? 'expired' : 'active' );
|
|
push @set, "status=" . $dbh->quote( $ban->{'status'} );
|
|
}
|
|
|
|
# banuntil
|
|
if ( $banuntil && $banuntil ne $ban->{'banuntil'} ) {
|
|
$ban->{'banuntil'} = ( $banuntil && $banuntil ne 'NULL' ) ? $banuntil : 0;
|
|
push @set,
|
|
"banuntil=" . ( $ban->{'banuntil'} ? $dbh->quote( $ban->{'banuntil'} ) : 'NULL' );
|
|
}
|
|
|
|
# bandate - must have a value
|
|
if ( $bandate && $bandate ne $ban->{'bandate'} ) {
|
|
$ban->{'bandate'} = $bandate;
|
|
push @set, "bandate=" . $dbh->quote( $ban->{'bandate'} );
|
|
}
|
|
|
|
# note - can be changed to blank
|
|
if ( defined $note && $note ne $ban->{'note'} ) {
|
|
$ban->{'note'} = $note;
|
|
push @set, "note=" . $dbh->quote( $ban->{'note'} );
|
|
}
|
|
|
|
# do update
|
|
$dbh->do( "UPDATE sysban SET " . join( ", ", @set ) . " WHERE banid=?", undef,
|
|
$ban->{'banid'} );
|
|
|
|
# log in statushistory
|
|
my $msg;
|
|
map {
|
|
$msg .= " " if $msg;
|
|
$msg .= "$_=$ban->{$_};"
|
|
} qw(banid status bandate banuntil what value note);
|
|
LJ::statushistory_add( 0, 0, 'sysban_mod', $msg );
|
|
|
|
print "MODIFIED: banid=$banid\n";
|
|
exit;
|
|
}
|