From b54f879f3539c298646449ede2e8d458fc305605 Mon Sep 17 00:00:00 2001 From: brain Date: Mon, 4 Apr 2005 17:55:48 +0000 Subject: 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 --- src/commands.cpp | 33 +++++++++++++++++++++++ src/inspircd.cpp | 42 +++++++++++++++++------------- src/xline.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 134 insertions(+), 20 deletions(-) (limited to 'src') 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); + } +} -- cgit v1.2.3