From: brain Date: Mon, 4 Apr 2005 17:55:48 +0000 (+0000) Subject: Added E:Lines, a form of ban exception that can prevent opers, netadmins etc from... X-Git-Tag: v2.0.23~10673 X-Git-Url: https://git.netwichtig.de/gitweb/?a=commitdiff_plain;h=b54f879f3539c298646449ede2e8d458fc305605;p=user%2Fhenk%2Fcode%2Finspircd.git Added E:Lines, a form of ban exception that can prevent opers, netadmins etc from being glined. Can be added and removed either in the config or by an oper with the correct permissions to use the /ELINE command git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@975 e03df62e-2008-0410-955e-edbf42e46eb7 --- diff --git a/docs/helpop.conf.example b/docs/helpop.conf.example index 583108b23..522250242 100644 --- a/docs/helpop.conf.example +++ b/docs/helpop.conf.example @@ -137,8 +137,9 @@ line18="U Show u-lined servers" line19="P Show online opers and their idle times" line20="I Show connect class permissions" - line21="-" - line22="Note that all /STATS use is broadcast to online IRC operators."> + line21="e Show e-lines (local ban exemptions)" + line22="-" + line23="Note that all /STATS use is broadcast to online IRC operators."> +#-#-#-#-#-#-#-#-#-#-#-#-#- BANLIST LIMITS #-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# # +# Use these tags to customise the ban limits on a per channel basis. # +# the tags are read from top to bottom, and any tag found which # +# matches the channels name applies the banlimit to that channel. # +# It is advisable to put an entry with the channel as '*' at the # +# bottom of the list. If none are specified or no maxbans tag is # +# matched, the banlist size defaults to 64 entries. # +# # + + + #-#-#-#-#-#-#-#-#-#-#-#-#-#-#- RTFM LINE -#-#-#-#-#-#-#-#-#-#-#-#-#-# # # @@ -353,6 +365,11 @@ # host - ident@hostname (wildcards possible) # # reason - Reason to display on disconnection # # # +# exception lines define a hostmask that is excempt from [kzg]lines # +# # +# host - ident@hostname (wildcards possible) # +# reason - Reason, shown only in /stats e # +# # @@ -364,6 +381,8 @@ + + #-#-#-#-#-#-#-#-#-#-#- ALIAS DEFINITIONS -#-#-#-#-#-#-#-#-#-#-#-#-#-# # # # If you have the m_alias.so module loaded, you may also define # diff --git a/include/commands.h b/include/commands.h index f1c383e08..1242671b3 100644 --- a/include/commands.h +++ b/include/commands.h @@ -77,6 +77,7 @@ void handle_kline(char **parameters, int pcnt, userrec *user); void handle_gline(char **parameters, int pcnt, userrec *user); void handle_zline(char **parameters, int pcnt, userrec *user); void handle_qline(char **parameters, int pcnt, userrec *user); +void handle_eline(char **parameters, int pcnt, userrec *user); void handle_server(char **parameters, int pcnt, userrec *user); /** Special functions for processing server to server traffic diff --git a/include/xline.h b/include/xline.h index 87f88518f..b5163ee58 100644 --- a/include/xline.h +++ b/include/xline.h @@ -79,6 +79,15 @@ class GLine : public XLine char hostmask[MAXBUF]; }; +class ELine : public XLine +{ + public: + /** Hostmask (ident@host) to match against + * May contain wildcards. + */ + char hostmask[MAXBUF]; +}; + /** ZLine class */ class ZLine : public XLine @@ -115,16 +124,19 @@ void add_gline(long duration, char* source, char* reason, char* hostmask); void add_qline(long duration, char* source, char* reason, char* nickname); void add_zline(long duration, char* source, char* reason, char* ipaddr); void add_kline(long duration, char* source, char* reason, char* hostmask); +void add_eline(long duration, char* source, char* reason, char* hostmask); bool del_gline(char* hostmask); bool del_qline(char* nickname); bool del_zline(char* ipaddr); bool del_kline(char* hostmask); +bool del_eline(char* hostmask); char* matches_qline(const char* nick); char* matches_gline(const char* host); char* matches_zline(const char* ipaddr); char* matches_kline(const char* host); +char* matches_exception(const char* host); void expire_lines(); void apply_lines(); @@ -133,6 +145,7 @@ void stats_k(userrec* user); void stats_g(userrec* user); void stats_q(userrec* user); void stats_z(userrec* user); +void stats_e(userrec* user); void gline_set_creation_time(char* host, time_t create_time); void qline_set_creation_time(char* nick, time_t create_time); @@ -144,5 +157,3 @@ bool qline_make_global(char* nickname); void sync_xlines(serverrec* serv, char* tcp_host); #endif - - diff --git a/src/commands.cpp b/src/commands.cpp index 75f0dd86d..2ae4e0049 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1293,6 +1293,11 @@ void handle_stats(char **parameters, int pcnt, userrec *user) stats_z(user); } + if (!strcmp(parameters[0],"e")) + { + stats_e(user); + } + /* stats m (list number of times each command has been used, plus bytecount) */ if (!strcmp(parameters[0],"m")) { @@ -3160,6 +3165,34 @@ void handle_kline(char **parameters, int pcnt, userrec *user) apply_lines(); } +void handle_eline(char **parameters, int pcnt, userrec *user) +{ + if (pcnt >= 3) + { + add_eline(duration(parameters[1]),user->nick,parameters[2],parameters[0]); + if (!duration(parameters[1])) + { + WriteOpers("*** %s added permenant E-line for %s.",user->nick,parameters[0]); + } + else + { + WriteOpers("*** %s added timed E-line for %s, expires in %d seconds.",user->nick,parameters[0],duration(parameters[1])); + } + } + else + { + if (del_eline(parameters[0])) + { + WriteOpers("*** %s Removed E-line on %s.",user->nick,parameters[0]); + } + else + { + WriteServ(user->fd,"NOTICE %s :*** E-Line %s not found in list, try /stats e.",user->nick,parameters[0]); + } + } + // no need to apply the lines for an eline +} + void handle_gline(char **parameters, int pcnt, userrec *user) { char netdata[MAXBUF]; diff --git a/src/inspircd.cpp b/src/inspircd.cpp index d979750b5..2ef0b53bc 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -2243,8 +2243,10 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip) if (clientlist.size() == MAXCLIENTS) kill_link(clientlist[tempnick],"No more connections allowed in this class"); + char* r = matches_zline(ip); - if (r) + char* e = matches_exception(ip); + if ((r) && (!e)) { char reason[MAXBUF]; snprintf(reason,MAXBUF,"Z-Lined: %s",r); @@ -2375,23 +2377,26 @@ void FullConnectUser(userrec* user) char match_against[MAXBUF]; snprintf(match_against,MAXBUF,"%s@%s",user->ident,user->host); - char* r = matches_gline(match_against); - if (r) - { - char reason[MAXBUF]; - snprintf(reason,MAXBUF,"G-Lined: %s",r); - kill_link_silent(user,reason); - return; - } - - r = matches_kline(user->host); - if (r) - { - char reason[MAXBUF]; - snprintf(reason,MAXBUF,"K-Lined: %s",r); - kill_link_silent(user,reason); - return; - } + char* e = matches_exception(match_against); + if (!e) + { + char* r = matches_gline(match_against); + if (r) + { + char reason[MAXBUF]; + snprintf(reason,MAXBUF,"G-Lined: %s",r); + kill_link_silent(user,reason); + return; + } + r = matches_kline(user->host); + if (r) + { + char reason[MAXBUF]; + snprintf(reason,MAXBUF,"K-Lined: %s",r); + kill_link_silent(user,reason); + return; + } + } WriteServ(user->fd,"NOTICE Auth :Welcome to \002%s\002!",Network); WriteServ(user->fd,"001 %s :Welcome to the %s IRC Network %s!%s@%s",user->nick,Network,user->nick,user->ident,user->host); @@ -2967,6 +2972,7 @@ void SetupCommandTable(void) createcommand("GLINE",handle_gline,'o',1); createcommand("ZLINE",handle_zline,'o',1); createcommand("QLINE",handle_qline,'o',1); + createcommand("ELINE",handle_eline,'o',1); createcommand("SERVER",handle_server,0,0); } diff --git a/src/xline.cpp b/src/xline.cpp index 15032b32a..ce6257a66 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -186,6 +186,7 @@ std::vector klines; std::vector glines; std::vector zlines; std::vector qlines; +std::vector elines; // Reads the default bans from the config file. // only a very small number of bans are defined @@ -222,6 +223,13 @@ void read_xline_defaults() add_kline(0,"",reason,host); log(DEBUG,"Read K line (badhost tag): host=%s reason=%s",host,reason); } + for (int i = 0; i < ConfValueEnum("exception",&config_f); i++) + { + ConfValue("exception","host",i,host,&config_f); + ConfValue("exception","reason",i,reason,&config_f); + add_eline(0,"",reason,host); + log(DEBUG,"Read E line (exception tag): host=%s reason=%s",host,reason); + } } // adds a g:line @@ -239,6 +247,21 @@ void add_gline(long duration, char* source, char* reason, char* hostmask) glines.push_back(item); } +// adds an e:line (exception to bans) + +void add_eline(long duration, char* source, char* reason, char* hostmask) +{ + del_eline(hostmask); + ELine item; + item.duration = duration; + strlcpy(item.hostmask,hostmask,MAXBUF); + strlcpy(item.reason,reason,MAXBUF); + strlcpy(item.source,source,MAXBUF); + item.n_matches = 0; + item.set_time = time(NULL); + elines.push_back(item); +} + // adds a q:line void add_qline(long duration, char* source, char* reason, char* nickname) @@ -301,6 +324,21 @@ bool del_gline(char* hostmask) return false; } +// deletes a e:line, returns true if the line existed and was removed + +bool del_eline(char* hostmask) +{ + for (std::vector::iterator i = elines.begin(); i != elines.end(); i++) + { + if (!strcasecmp(hostmask,i->hostmask)) + { + elines.erase(i); + return true; + } + } + return false; +} + // deletes a q:line, returns true if the line existed and was removed bool del_qline(char* nickname) @@ -430,6 +468,21 @@ char* matches_gline(const char* host) return NULL; } +char* matches_exception(const char* host) +{ + char host2[MAXBUF]; + snprintf(host2,MAXBUF,"*@%s",host); + for (std::vector::iterator i = elines.begin(); i != elines.end(); i++) + { + if ((match(host,i->hostmask)) || (match(host2,i->hostmask))) + { + return i->reason; + } + } + return NULL; +} + + void gline_set_creation_time(char* host, time_t create_time) { for (std::vector::iterator i = glines.begin(); i != glines.end(); i++) @@ -521,6 +574,17 @@ void expire_lines() } } + for (std::vector::iterator i = elines.begin(); i != elines.end(); i++) + { + if ((current > (i->duration + i->set_time)) && (i->duration > 0)) + { + WriteOpers("Expiring timed E-Line %s (set by %s %d seconds ago)",i->hostmask,i->source,i->duration); + elines.erase(i); + go_again = true; + break; + } + } + for (std::vector::iterator i = glines.begin(); i != glines.end(); i++) { if ((current > (i->duration + i->set_time)) && (i->duration > 0)) @@ -575,6 +639,12 @@ void apply_lines() if (!strcasecmp(u->second->server,ServerName)) { snprintf(host,MAXBUF,"%s@%s",u->second->ident,u->second->host); + if (elines.size()) + { + // ignore people matching exempts + if (matches_exception(host)) + continue; + } if (glines.size()) { char* check = matches_gline(host); @@ -660,5 +730,10 @@ void stats_z(userrec* user) } } - - +void stats_e(userrec* user) +{ + for (std::vector::iterator i = elines.begin(); i != elines.end(); i++) + { + WriteServ(user->fd,"223 %s :%s %d %d %s %s",user->nick,i->hostmask,i->set_time,i->duration,i->source,i->reason); + } +}