]>
jfr.im git - irc/SurrealServices/srsv.git/blob - branches/0.4.3/modules/serviceslibs/adminserv.pm
c7af59277fc7b1af3c031dba3831c9cc0954abcc
1 # This file is part of SurrealServices.
3 # SurrealServices is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # SurrealServices is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with SurrealServices; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 use SrSv
:: Text
:: Format
qw(columnar) ;
25 use SrSv
:: User
qw(get_user_nick get_user_id) ;
26 use SrSv
:: User
:: Notice
;
27 use SrSv
:: Help
qw( sendhelp ) ;
31 use SrSv
:: NickReg
:: Flags
qw(NRF_NOHIGHLIGHT nr_chk_flag_user) ;
33 use SrSv
:: MySQL
' $dbh ' ;
42 our ( %flags , @levels , @defflags , $allflags );
45 # BE CAREFUL CHANGING THESE
59 for ( my $i = scalar ( @flags ) - 1 ; $i >= 0 ; $i --) {
60 $flags { $flags [ $i ]} = 1 << $i ;
62 $allflags = ( 1 << scalar ( @flags )) - 1 ;
63 our @levels = ( 'Normal User' , 'HelpOp' , 'Operator' , 'Administrator' , 'Root' );
64 # BE CAREFUL CHANGING THESE
67 $flags { HELP
}, # HelpOp
68 $flags { HELP
}| $flags { FJOIN
}| $flags { QLINE
}| $flags { SUPER
}| $flags { FREEZE
}| $flags { KILL
}, # Operator
69 $flags { HELP
}| $flags { FJOIN
}| $flags { QLINE
}| $flags { SUPER
}| $flags { FREEZE
}| $flags { KILL
}|
70 $flags { HOLD
}| $flags { BOT
}| $flags { SERVOP
}| $flags { LOG
}, # Admin
75 our $asnick_default = 'AdminServ' ;
76 our $asnick = $asnick_default ;
80 $create_svsop , $delete_svsop , $rename_svsop ,
82 $get_svs_list , $get_all_svsops ,
84 $get_svs_level , $set_svs_level , $get_best_svs_level ,
86 $chk_pass , $get_pass , $set_pass
90 $create_svsop = $dbh -> prepare ( "INSERT IGNORE INTO svsop SELECT id, NULL, NULL FROM nickreg WHERE nick=?" );
91 $delete_svsop = $dbh -> prepare ( "DELETE FROM svsop USING svsop, nickreg WHERE nickreg.nick=? AND svsop.nrid=nickreg.id" );
93 $get_svs_list = $dbh -> prepare ( "SELECT nickreg.nick, svsop.adder FROM svsop, nickreg WHERE svsop.level=? AND svsop.nrid=nickreg.id ORDER BY nickreg.nick" );
94 $get_all_svsops = $dbh -> prepare ( "SELECT nickreg.nick, svsop.level, svsop.adder FROM svsop, nickreg WHERE svsop.nrid=nickreg.id ORDER BY svsop.level, nickreg.nick" );
96 $get_svs_level = $dbh -> prepare ( "SELECT svsop.level FROM svsop, nickalias WHERE nickalias.alias=? AND svsop.nrid=nickalias.nrid" );
97 $set_svs_level = $dbh -> prepare ( "UPDATE svsop, nickreg SET svsop.level=?, svsop.adder=? WHERE nickreg.nick=? AND svsop.nrid=nickreg.id" );
98 $get_best_svs_level = $dbh -> prepare ( "SELECT svsop.level, nickreg.nick FROM nickid, nickreg, svsop WHERE nickid.nrid=nickreg.id AND svsop.nrid=nickreg.id AND nickid.id=? ORDER BY level DESC LIMIT 1" );
100 $chk_pass = $dbh -> prepare ( "SELECT 1 FROM ircop WHERE nick=? AND pass=?" );
101 $get_pass = $dbh -> prepare ( "SELECT pass FROM ircop WHERE nick=?" );
102 $set_pass = $dbh -> prepare ( "UPDATE ircop SET pass=? WHERE nick=?" );
105 ### ADMINSERV COMMANDS ###
108 my ( $src , $dst , $msg ) = @_ ;
110 my @args = split ( /\s+/ , $msg );
111 my $cmd = shift @args ;
113 my $user = { NICK
=> $src , AGENT
=> $dst };
115 services
:: ulog
( $asnick , LOG_INFO
(), "cmd: [ $msg ]" , $user );
117 unless ( is_svsop
( $user ) or is_ircop
( $user )) {
118 notice
( $user , $err_deny );
119 ircd
:: globops
( $asnick , " \002 $src \002 failed access to $asnick $msg " );
123 if ( $cmd =~ /^svsop$/i ) {
124 my $cmd2 = shift @args ;
126 if ( $cmd2 =~ /^add$/i ) {
127 if ( @args == 2 and $args [ 1 ] =~ /^[aoh]$/i ) {
128 as_svs_add
( $user , $args [ 0 ], num_level
( $args [ 1 ]));
130 notice
( $user , 'Syntax: SVSOP ADD <nick> <A|O|H>' );
133 elsif ( $cmd2 =~ /^del$/i ) {
135 as_svs_del
( $user , $args [ 0 ]);
137 notice
( $user , 'Syntax: SVSOP DEL <nick>' );
140 elsif ( $cmd2 =~ /^list$/i ) {
141 if ( @args == 1 and $args [ 0 ] =~ /^[raoh]$/i ) {
142 as_svs_list
( $user , num_level
( $args [ 0 ]));
144 notice
( $user , 'Syntax: SVSOP LIST <R|A|O|H>' );
148 notice
( $user , 'Syntax: SVSOP <ADD|DEL|LIST> [...]' );
151 elsif ( $cmd =~ /^whois$/i ) {
153 as_whois
( $user , $args [ 0 ]);
155 notice
( $user , 'Syntax: WHOIS <nick>' );
158 elsif ( $cmd =~ /^help$/i ) {
159 sendhelp
( $user , 'adminserv' , @args )
161 elsif ( $cmd =~ /^staff$/i ) {
166 notice
( $user , 'Syntax: STAFF' );
170 notice
( $user , "Unrecognized command. For help, type: \002 /msg adminserv help \002 " );
174 sub as_svs_add
( $$$ ) {
175 my ( $user , $target_nick , $target_level ) = @_ ;
176 my $src = get_user_nick
( $user );
177 my $target_nickreg = nickserv
:: get_root_nick
( $target_nick );
178 my ( $src_level , $user_oper ) = get_best_svs_level
( $user );
180 if ( $target_level >= $src_level ) {
181 notice
( $user , $err_deny );
185 $create_svsop -> execute ( $target_nickreg );
186 $set_svs_level -> execute ( $target_level , $user_oper , $target_nickreg );
188 notice
( $user , " \002 $target_nick \002 is now a \002 Services $levels [ $target_level ] \002 ." );
189 wlog
( $asnick , LOG_INFO
(), " $src added $target_nickreg as a Services $levels [ $target_level ]." );
193 my ( $user , $target_nick ) = @_ ;
194 my $src = get_user_nick
( $user );
195 my $target_nickreg = nickserv
:: get_root_nick
( $target_nick );
197 if ( get_svs_level
( $target_nickreg ) >= get_svs_level
( $src )) {
198 notice
( $user , $err_deny );
202 $delete_svsop -> execute ( $target_nickreg );
203 notice
( $user , " \002 $target_nickreg \002 has been stripped of services rank." );
204 wlog
( $asnick , LOG_INFO
(), " $src stripped $target_nickreg of services rank." )
207 sub as_svs_list
( $$ ) {
208 my ( $user , $level ) = @_ ;
211 $get_svs_list -> execute ( $level );
213 while ( my ( $nick , $adder ) = $get_svs_list -> fetchrow_array ) {
214 push @data , [ $nick , "( $adder )" ];
217 notice
( $user , columnar
({ TITLE
=> "Services $levels [ $level ] list:" ,
218 NOHIGHLIGHT
=> nr_chk_flag_user
( $user , NRF_NOHIGHLIGHT
)}, @data ));
222 my ( $user , $nick ) = @_ ;
224 my ( $level , $root ) = get_best_svs_level
({ NICK
=> $nick });
225 notice
( $user , " \002 $nick \002 is a Services $levels [ $level ]" .( $level ? ' due to identification to the nick ' . " \002 $root \002 ." : '' ));
232 $get_all_svsops -> execute ();
234 while ( my ( $nick , $level , $adder ) = $get_all_svsops -> fetchrow_array ) {
235 push @data , [ $nick , $levels [ $level ], "( $adder )" ];
238 notice
( $user , columnar
({ TITLE
=> 'Staff list:' ,
239 NOHIGHLIGHT
=> nr_chk_flag_user
( $user , NRF_NOHIGHLIGHT
)}, @data ));
243 ### DATABASE UTILITY FUNCTIONS ###
245 sub validate_chg
( $$ ) {
246 my ( $user , $target_nick ) = @_ ;
249 unless ( $user_oper = is_svsop
( $user , S_ROOT
)) {
250 notice
( $user , $err_deny );
254 my $target_nickreg = nickserv
:: get_root_nick
( $target_nick );
255 unless ( $target_nickreg ) {
256 notice
( $user , "The nick \002 $target_nick \002 is not registered." );
260 return ( $target_nickreg , $user_oper );
264 my ( $user , $flag ) = @_ ;
265 my $nflag = $flags { $flag };
267 my ( $level , $nick ) = get_best_svs_level
( $user );
269 if ( $defflags [ $level ] & $nflag ) {
270 return $nick if (( $nflag == $flags { 'HELP' }) or is_ircop
( $user ));
277 my ( $user , $rlev ) = @_ ;
279 my ( $level , $nick ) = get_best_svs_level
( $user );
280 return $nick if ( defined ( $level ) and ! defined ( $rlev ));
282 if ( $level >= $rlev ) {
283 return $nick if (( $rlev == S_HELP
) or is_ircop
( $user ));
292 return undef if is_agent
( $user ->{ NICK
});
294 return $user ->{ IRCOP
} if ( exists ( $user ->{ IRCOP
}));
296 my %umodes = modes
:: splitumodes
( nickserv
:: get_user_modes
( $user ));
298 no warnings
'deprecated' ;
299 if (( $umodes { 'o' } eq '+' ) or ( $umodes { 'S' } eq '+' )) {
306 return $user ->{ IRCOP
};
310 # detect if a user belongs to another service like NeoStats. only works if they set umode +S
311 # is_ircop() includes is_service(), so no reason to call both.
314 return undef if is_agent
( $user ->{ NICK
});
316 return $user ->{ SERVICE
} if ( exists ( $user ->{ SERVICE
}));
318 my %umodes = modes
:: splitumodes
( nickserv
:: get_user_modes
( $user ));
320 if ( $umodes { 'S' } eq '+' ) {
321 $user ->{ SERVICE
} = 1 ;
325 $user ->{ SERVICE
} = 0 ;
328 return $user ->{ SERVICE
};
331 sub get_svs_level
($) {
334 return undef if is_agent
( $nick );
336 $get_svs_level -> execute ( $nick );
337 my ( $level ) = $get_svs_level -> fetchrow_array ;
342 sub get_best_svs_level
($) {
345 return undef if is_agent
( $user ->{ NICK
});
347 if ( exists ( $user ->{ SVSOP_LEVEL
}) && exists ( $user ->{ SVSOP_NICK
})) {
349 return ( $user ->{ SVSOP_LEVEL
}, $user ->{ SVSOP_NICK
});
351 return $user ->{ SVSOP_LEVEL
};
355 my $uid = get_user_id
( $user );
356 $get_best_svs_level -> execute ( $uid );
357 my ( $level , $nick ) = $get_best_svs_level -> fetchrow_array ;
359 $user ->{ SVSOP_LEVEL
} = $level ; $user ->{ SVSOP_NICK
} = $nick ;
362 return ( $level , $nick );
372 $x =~ tr/hoarHOAR/12341234/ ;