Automated merge with ssh://hg.atheme.org//hg/charybdis

This commit is contained in:
William Pitcock 2010-04-06 17:14:51 -05:00
commit bd44fc7b09
22 changed files with 519 additions and 204 deletions

View file

@ -457,6 +457,7 @@ general {
identify_command = "IDENTIFY"; identify_command = "IDENTIFY";
non_redundant_klines = yes; non_redundant_klines = yes;
warn_no_nline = yes; warn_no_nline = yes;
use_propagated_bans = yes;
stats_e_disabled = no; stats_e_disabled = no;
stats_c_oper_only=no; stats_c_oper_only=no;
stats_h_oper_only=no; stats_h_oper_only=no;
@ -474,6 +475,7 @@ general {
short_motd = no; short_motd = no;
ping_cookie = no; ping_cookie = no;
connect_timeout = 30 seconds; connect_timeout = 30 seconds;
default_ident_timeout = 5;
disable_auth = no; disable_auth = no;
no_oper_flood = yes; no_oper_flood = yes;
max_targets = 4; max_targets = 4;

View file

@ -1030,6 +1030,13 @@ general {
*/ */
warn_no_nline = yes; warn_no_nline = yes;
/* use propagated bans: KLINE, XLINE and RESV set fully propagated bans.
* That means the bans are part of the netburst and restarted/split
* servers will get them, but they will not apply to 3.2 and older
* servers at all.
*/
use_propagated_bans = yes;
/* stats e disabled: disable stats e. useful if server ips are /* stats e disabled: disable stats e. useful if server ips are
* exempted and you dont want them listing on irc. * exempted and you dont want them listing on irc.
*/ */
@ -1109,6 +1116,11 @@ general {
*/ */
connect_timeout = 30 seconds; connect_timeout = 30 seconds;
/* ident timeout: Amount of time (in seconds) that the IRCd will
* wait for a user to respond to an ident request.
*/
default_ident_timeout = 5;
/* disable auth: disables identd checking */ /* disable auth: disables identd checking */
disable_auth = no; disable_auth = no;

View file

@ -17,13 +17,14 @@ mapi_hfn_list_av1 adminonly_hfnlist[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static unsigned int mymode;
static int static int
_modinit(void) _modinit(void)
{ {
chmode_table['A'].mode_type = find_cflag_slot(); mymode = cflag_add('A', chm_staff);
chmode_table['A'].set_func = chm_staff; if (mymode == 0)
return -1;
construct_noparam_modes();
return 0; return 0;
} }
@ -31,9 +32,7 @@ _modinit(void)
static void static void
_moddeinit(void) _moddeinit(void)
{ {
chmode_table['A'].mode_type = 0; cflag_orphan('A');
construct_noparam_modes();
} }
DECLARE_MODULE_AV1(chm_adminonly, _modinit, _moddeinit, NULL, NULL, adminonly_hfnlist, "$Revision$"); DECLARE_MODULE_AV1(chm_adminonly, _modinit, _moddeinit, NULL, NULL, adminonly_hfnlist, "$Revision$");
@ -44,7 +43,7 @@ h_can_join(hook_data_channel *data)
struct Client *source_p = data->client; struct Client *source_p = data->client;
struct Channel *chptr = data->chptr; struct Channel *chptr = data->chptr;
if((chptr->mode.mode & chmode_flags['A']) && !IsAdmin(source_p)) { if((chptr->mode.mode & mymode) && !IsAdmin(source_p)) {
sendto_one_numeric(source_p, 519, "%s :Cannot join channel (+A) - you are not an IRC server administrator", chptr->chname); sendto_one_numeric(source_p, 519, "%s :Cannot join channel (+A) - you are not an IRC server administrator", chptr->chname);
data->approved = ERR_CUSTOM; data->approved = ERR_CUSTOM;
} }

View file

@ -17,7 +17,7 @@ mapi_hfn_list_av1 operonly_hfnlist[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static unsigned int mymode;
/* This is a simple example of how to use dynamic channel modes. /* This is a simple example of how to use dynamic channel modes.
* Not tested enough yet, use at own risk. * Not tested enough yet, use at own risk.
@ -26,27 +26,18 @@ mapi_hfn_list_av1 operonly_hfnlist[] = {
static int static int
_modinit(void) _modinit(void)
{ {
/* add the channel mode to the available slot */ mymode = cflag_add('O', chm_staff);
chmode_table['O'].mode_type = find_cflag_slot(); if (mymode == 0)
chmode_table['O'].set_func = chm_staff; return -1;
construct_noparam_modes();
return 0; return 0;
} }
/* Well, the first ugly thing is that we changle chmode_table in _modinit
* and chmode_flags in _moddeinit (different arrays) - must be fixed.
* -- dwr
*/
static void static void
_moddeinit(void) _moddeinit(void)
{ {
/* disable the channel mode and remove it from the available list */ cflag_orphan('O');
chmode_table['O'].mode_type = 0;
construct_noparam_modes();
} }
DECLARE_MODULE_AV1(chm_operonly, _modinit, _moddeinit, NULL, NULL, operonly_hfnlist, "$Revision$"); DECLARE_MODULE_AV1(chm_operonly, _modinit, _moddeinit, NULL, NULL, operonly_hfnlist, "$Revision$");
@ -57,7 +48,7 @@ h_can_join(hook_data_channel *data)
struct Client *source_p = data->client; struct Client *source_p = data->client;
struct Channel *chptr = data->chptr; struct Channel *chptr = data->chptr;
if((chptr->mode.mode & chmode_flags['O']) && !IsOper(source_p)) { if((chptr->mode.mode & mymode) && !IsOper(source_p)) {
sendto_one_numeric(source_p, 520, "%s :Cannot join channel (+O) - you are not an IRC operator", chptr->chname); sendto_one_numeric(source_p, 520, "%s :Cannot join channel (+O) - you are not an IRC operator", chptr->chname);
data->approved = ERR_CUSTOM; data->approved = ERR_CUSTOM;
} }

View file

@ -17,13 +17,14 @@ mapi_hfn_list_av1 sslonly_hfnlist[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static unsigned int mymode;
static int static int
_modinit(void) _modinit(void)
{ {
chmode_table['S'].mode_type = find_cflag_slot(); mymode = cflag_add('S', chm_simple);
chmode_table['S'].set_func = chm_simple; if (mymode == 0)
return -1;
construct_noparam_modes();
return 0; return 0;
} }
@ -32,9 +33,7 @@ _modinit(void)
static void static void
_moddeinit(void) _moddeinit(void)
{ {
chmode_table['S'].mode_type = 0; cflag_orphan('S');
construct_noparam_modes();
} }
DECLARE_MODULE_AV1(chm_sslonly, _modinit, _moddeinit, NULL, NULL, sslonly_hfnlist, "$Revision$"); DECLARE_MODULE_AV1(chm_sslonly, _modinit, _moddeinit, NULL, NULL, sslonly_hfnlist, "$Revision$");
@ -45,7 +44,7 @@ h_can_join(hook_data_channel *data)
struct Client *source_p = data->client; struct Client *source_p = data->client;
struct Channel *chptr = data->chptr; struct Channel *chptr = data->chptr;
if((chptr->mode.mode & chmode_flags['S']) && !IsSSLClient(source_p)) { if((chptr->mode.mode & mymode) && !IsSSLClient(source_p)) {
sendto_one_notice(source_p, ":Only users using SSL could join this channel!"); sendto_one_notice(source_p, ":Only users using SSL could join this channel!");
data->approved = ERR_CUSTOM; data->approved = ERR_CUSTOM;
} }

View file

@ -8,16 +8,16 @@ HELP INDEX INFO INVITE
ISON JOIN KICK KILL ISON JOIN KICK KILL
KLINE KNOCK LINKS LIST KLINE KNOCK LINKS LIST
LOCOPS LUSERS MAP MASKTRACE LOCOPS LUSERS MAP MASKTRACE
MODLIST MODLOAD MODRESTART MODUNLOAD MODLIST MODLOAD MODRELOAD MODRESTART
MOTD NAMES NICK NOTICE MODUNLOAD MOTD NAMES NICK
OPER OPERSPY OPERWALL PART NOTICE OPER OPERSPY OPERWALL
PASS PING PONG POST PART PASS PING PONG
PRIVMSG QUIT REHASH RESTART POST PRIVMSG QUIT REHASH
RESV SCAN SERVER SET RESTART RESV SCAN SERVER
SJOIN SNOMASK SQUIT STATS SET SJOIN SNOMASK SQUIT
SVINFO TESTGECOS TESTLINE TESTMASK STATS SVINFO TESTGECOS TESTLINE
TIME TOPIC TRACE UHELP TESTMASK TIME TOPIC TRACE
UMODE UNDLINE UNKLINE UNREJECT UHELP UMODE UNDLINE UNKLINE
UNRESV UNXLINE USER USERHOST UNREJECT UNRESV UNXLINE USER
USERS VERSION WALLOPS WHO USERHOST USERS VERSION WALLOPS
WHOIS WHOWAS XLINE WHO WHOIS WHOWAS XLINE

6
help/opers/modreload Normal file
View file

@ -0,0 +1,6 @@
MODRELOAD <module.so>
-- Reload a module in the ircd
Use just the module name, the path is not needed.
- Requires Oper Priv: A

View file

@ -29,14 +29,14 @@ X f - Shows File Descriptors
^ o - Shows operator blocks (Old O: lines) ^ o - Shows operator blocks (Old O: lines)
^ P - Shows configured ports ^ P - Shows configured ports
p - Shows online opers p - Shows online opers
* q - Shows temporary resv'd nicks and channels * q - Shows temporary and global resv'd nicks and channels
* Q - Shows resv'd nicks and channels * Q - Shows resv'd nicks and channels
* r - Shows resource usage by ircd * r - Shows resource usage by ircd
* t - Shows generic server stats * t - Shows generic server stats
* U - Shows shared blocks (Old U: lines) * U - Shows shared blocks (Old U: lines)
u - Shows server uptime u - Shows server uptime
^ v - Shows connected servers and brief status information ^ v - Shows connected servers and brief status information
* x - Shows temporary gecos bans * x - Shows temporary and global gecos bans
* X - Shows gecos bans (Old X: lines) * X - Shows gecos bans (Old X: lines)
^ y - Shows connection classes (Old Y: lines) ^ y - Shows connection classes (Old Y: lines)
* z - Shows memory stats * z - Shows memory stats

View file

@ -126,11 +126,13 @@ struct ChCapCombo
int cap_no; int cap_no;
}; };
typedef void (*ChannelModeFunc)(struct Client *source_p, struct Channel *chptr,
int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type);
struct ChannelMode struct ChannelMode
{ {
void (*set_func) (struct Client * source_p, struct Channel * chptr, ChannelModeFunc set_func;
int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type);
long mode_type; long mode_type;
}; };
@ -257,6 +259,8 @@ extern void unset_chcap_usage_counts(struct Client *serv_p);
extern void send_cap_mode_changes(struct Client *client_p, struct Client *source_p, extern void send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
struct Channel *chptr, struct ChModeChange foo[], int); struct Channel *chptr, struct ChModeChange foo[], int);
void resv_chan_forcepart(const char *name, const char *reason, int temp_time);
extern void set_channel_mode(struct Client *client_p, struct Client *source_p, extern void set_channel_mode(struct Client *client_p, struct Client *source_p,
struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]); struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]);
extern void set_channel_mlock(struct Client *client_p, struct Client *source_p, extern void set_channel_mlock(struct Client *client_p, struct Client *source_p,

View file

@ -73,9 +73,9 @@ extern void chm_voice(struct Client *source_p, struct Channel *chptr,
int alevel, int parc, int *parn, int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type); const char **parv, int *errors, int dir, char c, long mode_type);
extern void construct_noparam_modes(void); extern unsigned int cflag_add(char c, ChannelModeFunc function);
extern void find_orphaned_cflags(void); extern void cflag_orphan(char c);
extern unsigned int find_cflag_slot(void); extern void construct_cflags_strings(void);
extern char cflagsbuf[256]; extern char cflagsbuf[256];
extern char cflagsmyinfo[256]; extern char cflagsmyinfo[256];

View file

@ -206,6 +206,7 @@ struct config_file_entry
int min_nonwildcard_simple; int min_nonwildcard_simple;
int default_floodcount; int default_floodcount;
int client_flood; int client_flood;
int default_ident_timeout;
int use_egd; int use_egd;
int ping_cookie; int ping_cookie;
int tkline_expire_notices; int tkline_expire_notices;
@ -223,6 +224,7 @@ struct config_file_entry
int default_umodes; int default_umodes;
int global_snotices; int global_snotices;
int operspy_dont_care_user_info; int operspy_dont_care_user_info;
int use_propagated_bans;
}; };
struct config_channel_entry struct config_channel_entry
@ -326,6 +328,7 @@ extern void free_conf(struct ConfItem *);
extern rb_dlink_node *find_prop_ban(unsigned int status, const char *user, const char *host); extern rb_dlink_node *find_prop_ban(unsigned int status, const char *user, const char *host);
extern void deactivate_conf(struct ConfItem *, rb_dlink_node *); extern void deactivate_conf(struct ConfItem *, rb_dlink_node *);
extern void replace_old_ban(struct ConfItem *);
extern void read_conf_files(int cold); extern void read_conf_files(int cold);

View file

@ -29,6 +29,7 @@
#include "stdinc.h" #include "stdinc.h"
#include "send.h" #include "send.h"
#include "channel.h"
#include "client.h" #include "client.h"
#include "common.h" #include "common.h"
#include "config.h" #include "config.h"
@ -75,6 +76,7 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
time_t created, hold, lifetime; time_t created, hold, lifetime;
char *p; char *p;
int act; int act;
int valid;
if (strlen(parv[1]) != 1) if (strlen(parv[1]) != 1)
{ {
@ -89,6 +91,15 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
ntype = CONF_KILL; ntype = CONF_KILL;
stype = "K-Line"; stype = "K-Line";
break; break;
case 'X':
ntype = CONF_XLINE;
stype = "X-Line";
break;
case 'R':
ntype = IsChannelName(parv[3]) ? CONF_RESV_CHANNEL :
CONF_RESV_NICK;
stype = "RESV";
break;
default: default:
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"Unknown BAN type %s from %s", "Unknown BAN type %s from %s",
@ -153,22 +164,30 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
aconf->info.oper = operhash_add(oper); aconf->info.oper = operhash_add(oper);
aconf->created = created; aconf->created = created;
aconf->hold = hold; aconf->hold = hold;
p = strchr(parv[parc - 1], '|'); if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL)
if (p == NULL)
aconf->passwd = rb_strdup(parv[parc - 1]); aconf->passwd = rb_strdup(parv[parc - 1]);
else else
{ {
aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1); aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1);
aconf->spasswd = rb_strdup(p + 1); aconf->spasswd = rb_strdup(p + 1);
} }
if (act && hold != created && switch (ntype)
!(ntype == CONF_KILL ? {
valid_wild_card(aconf->user, aconf->host) : case CONF_KILL:
valid_wild_card_simple(aconf->host))) valid = valid_wild_card(aconf->user, aconf->host);
break;
case CONF_RESV_CHANNEL:
valid = 1;
break;
default:
valid = valid_wild_card_simple(aconf->host);
break;
}
if (act && hold != created && !valid)
{ {
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters", "Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters",
(hold - rb_current_time()) / 60, (int)((hold - rb_current_time()) / 60),
stype, stype,
IsServer(source_p) ? source_p->name : get_oper_name(source_p), IsServer(source_p) ? source_p->name : get_oper_name(source_p),
strcmp(parv[7], "*") ? " on behalf of " : "", strcmp(parv[7], "*") ? " on behalf of " : "",
@ -191,7 +210,7 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s added global %d min. %s%s%s for [%s%s%s] [%s]", "%s added global %d min. %s%s%s for [%s%s%s] [%s]",
IsServer(source_p) ? source_p->name : get_oper_name(source_p), IsServer(source_p) ? source_p->name : get_oper_name(source_p),
(hold - rb_current_time()) / 60, (int)((hold - rb_current_time()) / 60),
stype, stype,
strcmp(parv[7], "*") ? " from " : "", strcmp(parv[7], "*") ? " from " : "",
strcmp(parv[7], "*") ? parv[7] : "", strcmp(parv[7], "*") ? parv[7] : "",
@ -199,10 +218,12 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
aconf->user ? "@" : "", aconf->user ? "@" : "",
aconf->host, aconf->host,
parv[parc - 1]); parv[parc - 1]);
ilog(L_KLINE, "%s %s %d %s %s %s", parv[1], ilog(L_KLINE, "%s %s %d %s%s%s %s", parv[1],
IsServer(source_p) ? source_p->name : get_oper_name(source_p), IsServer(source_p) ? source_p->name : get_oper_name(source_p),
(hold - rb_current_time()) / 60, (int)((hold - rb_current_time()) / 60),
aconf->user, aconf->host, aconf->user ? aconf->user : "",
aconf->user ? " " : "",
aconf->host,
parv[parc - 1]); parv[parc - 1]);
aconf->status &= ~CONF_ILLEGAL; aconf->status &= ~CONF_ILLEGAL;
} }
@ -217,9 +238,11 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
aconf->host, aconf->host,
strcmp(parv[7], "*") ? " on behalf of " : "", strcmp(parv[7], "*") ? " on behalf of " : "",
strcmp(parv[7], "*") ? parv[7] : ""); strcmp(parv[7], "*") ? parv[7] : "");
ilog(L_KLINE, "U%s %s %s %s", parv[1], ilog(L_KLINE, "U%s %s %s%s %s", parv[1],
IsServer(source_p) ? source_p->name : get_oper_name(source_p), IsServer(source_p) ? source_p->name : get_oper_name(source_p),
aconf->user, aconf->host); aconf->user ? aconf->user : "",
aconf->user ? " " : "",
aconf->host);
} }
switch (ntype) switch (ntype)
{ {
@ -244,6 +267,26 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
check_klines(); check_klines();
} }
break; break;
case CONF_XLINE:
if (aconf->status & CONF_ILLEGAL)
remove_reject_mask(aconf->host, NULL);
else
{
rb_dlinkAddAlloc(aconf, &xline_conf_list);
check_xlines();
}
break;
case CONF_RESV_CHANNEL:
if (!(aconf->status & CONF_ILLEGAL))
{
add_to_resv_hash(aconf->host, aconf);
resv_chan_forcepart(aconf->host, aconf->passwd, hold - rb_current_time());
}
break;
case CONF_RESV_NICK:
if (!(aconf->status & CONF_ILLEGAL))
rb_dlinkAddAlloc(aconf, &resv_conf_list);
break;
} }
sendto_server(client_p, NULL, CAP_BAN|CAP_TS6, NOCAPS, sendto_server(client_p, NULL, CAP_BAN|CAP_TS6, NOCAPS,
":%s BAN %s %s %s %s %s %s %s :%s", ":%s BAN %s %s %s %s %s %s %s :%s",

View file

@ -175,7 +175,7 @@ clicap_generate(struct Client *source_p, const char *subcmd, int flags, int clea
char *p; char *p;
int buflen = 0; int buflen = 0;
int curlen, mlen; int curlen, mlen;
int i; size_t i;
mlen = rb_sprintf(buf, ":%s CAP %s %s", mlen = rb_sprintf(buf, ":%s CAP %s %s",
me.name, me.name,

View file

@ -133,6 +133,12 @@ static struct InfoStruct info_table[] = {
&ConfigFileEntry.connect_timeout, &ConfigFileEntry.connect_timeout,
"Connect timeout for connections to servers" "Connect timeout for connections to servers"
}, },
{
"default_ident_timeout",
OUTPUT_DECIMAL,
&ConfigFileEntry.default_ident_timeout,
"Amount of time the server waits for ident responses from clients",
},
{ {
"default_floodcount", "default_floodcount",
OUTPUT_DECIMAL, OUTPUT_DECIMAL,
@ -482,6 +488,12 @@ static struct InfoStruct info_table[] = {
&ConfigFileEntry.warn_no_nline, &ConfigFileEntry.warn_no_nline,
"Display warning if connecting server lacks N-line" "Display warning if connecting server lacks N-line"
}, },
{
"use_propagated_bans",
OUTPUT_BOOLEAN,
&ConfigFileEntry.use_propagated_bans,
"KLINE sets fully propagated bans"
},
{ {
"default_split_server_count", "default_split_server_count",
OUTPUT_DECIMAL, OUTPUT_DECIMAL,

View file

@ -107,7 +107,7 @@ mo_kline(struct Client *client_p, struct Client *source_p, int parc, const char
struct ConfItem *aconf; struct ConfItem *aconf;
int tkline_time = 0; int tkline_time = 0;
int loc = 1; int loc = 1;
int propagated = 1; int propagated = ConfigFileEntry.use_propagated_bans;
if(!IsOperK(source_p)) if(!IsOperK(source_p))
{ {
@ -297,7 +297,7 @@ handle_remote_kline(struct Client *source_p, int tkline_time,
":Please include at least %d non-wildcard " ":Please include at least %d non-wildcard "
"characters with the user@host", "characters with the user@host",
ConfigFileEntry.min_nonwildcard); ConfigFileEntry.min_nonwildcard);
return 0; return;
} }
if(already_placed_kline(source_p, user, host, tkline_time)) if(already_placed_kline(source_p, user, host, tkline_time))
@ -584,32 +584,11 @@ static void
apply_prop_kline(struct Client *source_p, struct ConfItem *aconf, apply_prop_kline(struct Client *source_p, struct ConfItem *aconf,
const char *reason, const char *oper_reason, int tkline_time) const char *reason, const char *oper_reason, int tkline_time)
{ {
rb_dlink_node *ptr;
struct ConfItem *oldconf;
aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY; aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY;
aconf->hold = rb_current_time() + tkline_time; aconf->hold = rb_current_time() + tkline_time;
aconf->lifetime = aconf->hold; aconf->lifetime = aconf->hold;
ptr = find_prop_ban(aconf->status, aconf->user, aconf->host); replace_old_ban(aconf);
if(ptr != NULL)
{
oldconf = ptr->data;
/* Remember at least as long as the old one. */
if(oldconf->lifetime > aconf->lifetime)
aconf->lifetime = oldconf->lifetime;
/* Force creation time to increase. */
if(oldconf->created >= aconf->created)
aconf->created = oldconf->created + 1;
/* Leave at least one second of validity. */
if(aconf->hold <= aconf->created)
aconf->hold = aconf->created + 1;
if(aconf->lifetime < aconf->hold)
aconf->lifetime = aconf->hold;
/* Tell deactivate_conf() to destroy it. */
oldconf->lifetime = rb_current_time();
deactivate_conf(oldconf, ptr);
}
rb_dlinkAddAlloc(aconf, &prop_bans); rb_dlinkAddAlloc(aconf, &prop_bans);
add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf); add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);

View file

@ -62,15 +62,14 @@ mapi_clist_av1 resv_clist[] = { &resv_msgtab, &unresv_msgtab, NULL };
DECLARE_MODULE_AV1(resv, NULL, NULL, resv_clist, NULL, NULL, "$Revision$"); DECLARE_MODULE_AV1(resv, NULL, NULL, resv_clist, NULL, NULL, "$Revision$");
static void parse_resv(struct Client *source_p, const char *name, static void parse_resv(struct Client *source_p, const char *name,
const char *reason, int temp_time); const char *reason, int temp_time, int propagated);
static void propagate_resv(struct Client *source_p, const char *target, static void propagate_resv(struct Client *source_p, const char *target,
int temp_time, const char *name, const char *reason); int temp_time, const char *name, const char *reason);
static void cluster_resv(struct Client *source_p, int temp_time, static void cluster_resv(struct Client *source_p, int temp_time,
const char *name, const char *reason); const char *name, const char *reason);
static void handle_remote_unresv(struct Client *source_p, const char *name); static void handle_remote_unresv(struct Client *source_p, const char *name);
static void remove_resv(struct Client *source_p, const char *name); static void remove_resv(struct Client *source_p, const char *name, int propagated);
static void resv_chan_forcepart(const char *name, const char *reason, int temp_time);
/* /*
* mo_resv() * mo_resv()
@ -86,6 +85,7 @@ mo_resv(struct Client *client_p, struct Client *source_p, int parc, const char *
const char *target_server = NULL; const char *target_server = NULL;
int temp_time; int temp_time;
int loc = 1; int loc = 1;
int propagated = ConfigFileEntry.use_propagated_bans;
if(!IsOperResv(source_p)) if(!IsOperResv(source_p))
{ {
@ -115,6 +115,9 @@ mo_resv(struct Client *client_p, struct Client *source_p, int parc, const char *
target_server = parv[loc + 1]; target_server = parv[loc + 1];
loc += 2; loc += 2;
/* Set as local-only. */
propagated = 0;
} }
if(parc <= loc || EmptyString(parv[loc])) if(parc <= loc || EmptyString(parv[loc]))
@ -133,10 +136,16 @@ mo_resv(struct Client *client_p, struct Client *source_p, int parc, const char *
if(match(target_server, me.name) == 0) if(match(target_server, me.name) == 0)
return 0; return 0;
} }
else if(rb_dlink_list_length(&cluster_conf_list) > 0) else if(!propagated && rb_dlink_list_length(&cluster_conf_list) > 0)
cluster_resv(source_p, temp_time, name, reason); cluster_resv(source_p, temp_time, name, reason);
parse_resv(source_p, name, reason, temp_time); if(propagated && temp_time == 0)
{
sendto_one_notice(source_p, ":Cannot set a permanent global ban");
return 0;
}
parse_resv(source_p, name, reason, temp_time, propagated);
return 0; return 0;
} }
@ -161,7 +170,7 @@ ms_resv(struct Client *client_p, struct Client *source_p, int parc, const char *
if(!IsPerson(source_p)) if(!IsPerson(source_p))
return 0; return 0;
parse_resv(source_p, parv[2], parv[3], 0); parse_resv(source_p, parv[2], parv[3], 0, 0);
return 0; return 0;
} }
@ -172,7 +181,7 @@ me_resv(struct Client *client_p, struct Client *source_p, int parc, const char *
if(!IsPerson(source_p)) if(!IsPerson(source_p))
return 0; return 0;
parse_resv(source_p, parv[2], parv[4], atoi(parv[1])); parse_resv(source_p, parv[2], parv[4], atoi(parv[1]), 0);
return 0; return 0;
} }
@ -185,7 +194,7 @@ me_resv(struct Client *client_p, struct Client *source_p, int parc, const char *
* side effects - will parse the resv and create it if valid * side effects - will parse the resv and create it if valid
*/ */
static void static void
parse_resv(struct Client *source_p, const char *name, const char *reason, int temp_time) parse_resv(struct Client *source_p, const char *name, const char *reason, int temp_time, int propagated)
{ {
struct ConfItem *aconf; struct ConfItem *aconf;
@ -223,10 +232,32 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
aconf->host = rb_strdup(name); aconf->host = rb_strdup(name);
aconf->passwd = rb_strdup(reason); aconf->passwd = rb_strdup(reason);
aconf->info.oper = operhash_add(get_oper_name(source_p)); aconf->info.oper = operhash_add(get_oper_name(source_p));
add_to_resv_hash(aconf->host, aconf);
resv_chan_forcepart(aconf->host, aconf->passwd, temp_time);
if(temp_time > 0) if(propagated)
{
aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY;
aconf->hold = rb_current_time() + temp_time;
aconf->lifetime = aconf->hold;
replace_old_ban(aconf);
rb_dlinkAddAlloc(aconf, &prop_bans);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s added global %d min. RESV for [%s] [%s]",
get_oper_name(source_p), temp_time / 60,
name, reason);
ilog(L_KLINE, "R %s %d %s %s",
get_oper_name(source_p), temp_time / 60, name, reason);
sendto_one_notice(source_p, ":Added global %d min. RESV [%s]",
temp_time / 60, name);
sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
":%s BAN R * %s %lu %d %d * :%s",
source_p->id, aconf->host,
(unsigned long)aconf->created,
(int)(aconf->hold - aconf->created),
(int)(aconf->lifetime - aconf->created),
reason);
}
else if(temp_time > 0)
{ {
aconf->hold = rb_current_time() + temp_time; aconf->hold = rb_current_time() + temp_time;
@ -250,6 +281,9 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
bandb_add(BANDB_RESV, source_p, aconf->host, NULL, aconf->passwd, NULL, 0); bandb_add(BANDB_RESV, source_p, aconf->host, NULL, aconf->passwd, NULL, 0);
} }
add_to_resv_hash(aconf->host, aconf);
resv_chan_forcepart(aconf->host, aconf->passwd, temp_time);
} }
else if(clean_resv_nick(name)) else if(clean_resv_nick(name))
{ {
@ -288,9 +322,32 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
aconf->host = rb_strdup(name); aconf->host = rb_strdup(name);
aconf->passwd = rb_strdup(reason); aconf->passwd = rb_strdup(reason);
aconf->info.oper = operhash_add(get_oper_name(source_p)); aconf->info.oper = operhash_add(get_oper_name(source_p));
rb_dlinkAddAlloc(aconf, &resv_conf_list);
if(temp_time > 0) if(propagated)
{
aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY;
aconf->hold = rb_current_time() + temp_time;
aconf->lifetime = aconf->hold;
replace_old_ban(aconf);
rb_dlinkAddAlloc(aconf, &prop_bans);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s added global %d min. RESV for [%s] [%s]",
get_oper_name(source_p), temp_time / 60,
name, reason);
ilog(L_KLINE, "R %s %d %s %s",
get_oper_name(source_p), temp_time / 60, name, reason);
sendto_one_notice(source_p, ":Added global %d min. RESV [%s]",
temp_time / 60, name);
sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
":%s BAN R * %s %lu %d %d * :%s",
source_p->id, aconf->host,
(unsigned long)aconf->created,
(int)(aconf->hold - aconf->created),
(int)(aconf->lifetime - aconf->created),
reason);
}
else if(temp_time > 0)
{ {
aconf->hold = rb_current_time() + temp_time; aconf->hold = rb_current_time() + temp_time;
@ -314,6 +371,8 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
bandb_add(BANDB_RESV, source_p, aconf->host, NULL, aconf->passwd, NULL, 0); bandb_add(BANDB_RESV, source_p, aconf->host, NULL, aconf->passwd, NULL, 0);
} }
rb_dlinkAddAlloc(aconf, &resv_conf_list);
} }
else else
sendto_one_notice(source_p, ":You have specified an invalid resv: [%s]", name); sendto_one_notice(source_p, ":You have specified an invalid resv: [%s]", name);
@ -380,6 +439,8 @@ cluster_resv(struct Client *source_p, int temp_time, const char *name, const cha
static int static int
mo_unresv(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) mo_unresv(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{ {
int propagated = 1;
if(!IsOperResv(source_p)) if(!IsOperResv(source_p))
{ {
sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "resv"); sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "resv");
@ -399,11 +460,16 @@ mo_unresv(struct Client *client_p, struct Client *source_p, int parc, const char
if(match(parv[3], me.name) == 0) if(match(parv[3], me.name) == 0)
return 0; return 0;
propagated = 0;
} }
#if 0
else if(rb_dlink_list_length(&cluster_conf_list) > 0) else if(rb_dlink_list_length(&cluster_conf_list) > 0)
cluster_generic(source_p, "UNRESV", SHARED_UNRESV, CAP_CLUSTER, "%s", parv[1]); cluster_generic(source_p, "UNRESV", SHARED_UNRESV, CAP_CLUSTER, "%s", parv[1]);
#endif
/* cluster{} moved to remove_resv */
remove_resv(source_p, parv[1]); remove_resv(source_p, parv[1], propagated);
return 0; return 0;
} }
@ -448,24 +514,63 @@ handle_remote_unresv(struct Client *source_p, const char *name)
source_p->servptr->name, SHARED_UNRESV)) source_p->servptr->name, SHARED_UNRESV))
return; return;
remove_resv(source_p, name); remove_resv(source_p, name, 0);
return; return;
} }
static void static void
remove_resv(struct Client *source_p, const char *name) remove_resv(struct Client *source_p, const char *name, int propagated)
{ {
struct ConfItem *aconf = NULL; struct ConfItem *aconf = NULL;
rb_dlink_node *ptr;
if(IsChannelName(name)) if(IsChannelName(name))
{ {
if((aconf = hash_find_resv(name)) == NULL) if((aconf = hash_find_resv(name)) == NULL)
{ {
if(propagated && rb_dlink_list_length(&cluster_conf_list))
cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER, "%s", name);
sendto_one_notice(source_p, ":No RESV for %s", name); sendto_one_notice(source_p, ":No RESV for %s", name);
return; return;
} }
if(aconf->lifetime)
{
if(!propagated)
{
sendto_one_notice(source_p, ":Cannot remove global RESV %s on specific servers", name);
return;
}
ptr = rb_dlinkFind(aconf, &prop_bans);
if(ptr == NULL)
return;
sendto_one_notice(source_p, ":RESV for [%s] is removed", name);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s has removed the global RESV for: [%s]",
get_oper_name(source_p), name);
ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name);
if(aconf->created < rb_current_time())
aconf->created = rb_current_time();
else
aconf->created++;
aconf->hold = aconf->created;
operhash_delete(aconf->info.oper);
aconf->info.oper = operhash_add(get_oper_name(source_p));
aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY;
sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
":%s BAN R * %s %lu %d %d * :*",
source_p->id, aconf->host,
(unsigned long)aconf->created,
0,
(int)(aconf->lifetime - aconf->created));
deactivate_conf(aconf, ptr);
return;
}
else if(propagated && rb_dlink_list_length(&cluster_conf_list) > 0)
cluster_generic(source_p, "UNRESV", SHARED_UNRESV, CAP_CLUSTER, "%s", name);
sendto_one_notice(source_p, ":RESV for [%s] is removed", name); sendto_one_notice(source_p, ":RESV for [%s] is removed", name);
ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name); ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name);
if(!aconf->hold) if(!aconf->hold)
@ -485,8 +590,6 @@ remove_resv(struct Client *source_p, const char *name)
} }
else else
{ {
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, resv_conf_list.head) RB_DLINK_FOREACH(ptr, resv_conf_list.head)
{ {
aconf = ptr->data; aconf = ptr->data;
@ -499,19 +602,62 @@ remove_resv(struct Client *source_p, const char *name)
if(aconf == NULL) if(aconf == NULL)
{ {
if(propagated && rb_dlink_list_length(&cluster_conf_list))
cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER, "%s", name);
sendto_one_notice(source_p, ":No RESV for %s", name); sendto_one_notice(source_p, ":No RESV for %s", name);
return; return;
} }
if(!aconf->hold) if(aconf->lifetime)
bandb_del(BANDB_RESV, aconf->host, NULL);
else
{ {
if(!propagated)
{
sendto_one_notice(source_p, ":Cannot remove global RESV %s on specific servers", name);
return;
}
ptr = rb_dlinkFind(aconf, &prop_bans);
if(ptr == NULL)
return;
sendto_one_notice(source_p, ":RESV for [%s] is removed", name); sendto_one_notice(source_p, ":RESV for [%s] is removed", name);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s has removed the global RESV for: [%s]",
get_oper_name(source_p), name);
ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name);
if(aconf->created < rb_current_time())
aconf->created = rb_current_time();
else
aconf->created++;
aconf->hold = aconf->created;
operhash_delete(aconf->info.oper);
aconf->info.oper = operhash_add(get_oper_name(source_p));
aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY;
sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
":%s BAN R * %s %lu %d %d * :*",
source_p->id, aconf->host,
(unsigned long)aconf->created,
0,
(int)(aconf->lifetime - aconf->created));
deactivate_conf(aconf, ptr);
return;
}
else if(propagated && rb_dlink_list_length(&cluster_conf_list) > 0)
cluster_generic(source_p, "UNRESV", SHARED_UNRESV, CAP_CLUSTER, "%s", name);
sendto_one_notice(source_p, ":RESV for [%s] is removed", name);
ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name);
if(!aconf->hold)
{
bandb_del(BANDB_RESV, aconf->host, NULL);
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s has removed the RESV for: [%s]", "%s has removed the RESV for: [%s]",
get_oper_name(source_p), name); get_oper_name(source_p), name);
ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name); }
else
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s has removed the temporary RESV for: [%s]",
get_oper_name(source_p), name);
} }
/* already have ptr from the loop above.. */ /* already have ptr from the loop above.. */
rb_dlinkDestroy(ptr, &resv_conf_list); rb_dlinkDestroy(ptr, &resv_conf_list);
@ -520,54 +666,3 @@ remove_resv(struct Client *source_p, const char *name)
return; return;
} }
static void
resv_chan_forcepart(const char *name, const char *reason, int temp_time)
{
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
struct Channel *chptr;
struct membership *msptr;
struct Client *target_p;
if(!ConfigChannel.resv_forcepart)
return;
/* for each user on our server in the channel list
* send them a PART, and notify opers.
*/
chptr = find_channel(name);
if(chptr != NULL)
{
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
{
msptr = ptr->data;
target_p = msptr->client_p;
if(IsExemptResv(target_p))
continue;
sendto_server(target_p, chptr, CAP_TS6, NOCAPS,
":%s PART %s", target_p->id, chptr->chname);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
target_p->name, target_p->username,
target_p->host, chptr->chname, target_p->name);
remove_user_from_channel(msptr);
/* notify opers & user they were removed from the channel */
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Forced PART for %s!%s@%s from %s (%s)",
target_p->name, target_p->username,
target_p->host, name, reason);
if(temp_time > 0)
sendto_one_notice(target_p, ":*** Channel %s is temporarily unavailable on this server.",
name);
else
sendto_one_notice(target_p, ":*** Channel %s is no longer available on this server.",
name);
}
}
}

View file

@ -79,7 +79,7 @@ DECLARE_MODULE_AV1(xline, NULL, NULL, xline_clist, NULL, NULL, "$Revision$");
static int valid_xline(struct Client *, const char *, const char *); static int valid_xline(struct Client *, const char *, const char *);
static void apply_xline(struct Client *client_p, const char *name, static void apply_xline(struct Client *client_p, const char *name,
const char *reason, int temp_time); const char *reason, int temp_time, int propagated);
static void propagate_xline(struct Client *source_p, const char *target, static void propagate_xline(struct Client *source_p, const char *target,
int temp_time, const char *name, const char *type, const char *reason); int temp_time, const char *name, const char *type, const char *reason);
static void cluster_xline(struct Client *source_p, int temp_time, static void cluster_xline(struct Client *source_p, int temp_time,
@ -89,7 +89,8 @@ static void handle_remote_xline(struct Client *source_p, int temp_time,
const char *name, const char *reason); const char *name, const char *reason);
static void handle_remote_unxline(struct Client *source_p, const char *name); static void handle_remote_unxline(struct Client *source_p, const char *name);
static void remove_xline(struct Client *source_p, const char *name); static void remove_xline(struct Client *source_p, const char *name,
int propagated);
/* m_xline() /* m_xline()
@ -107,6 +108,7 @@ mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char
const char *target_server = NULL; const char *target_server = NULL;
int temp_time; int temp_time;
int loc = 1; int loc = 1;
int propagated = ConfigFileEntry.use_propagated_bans;
if(!IsOperXline(source_p)) if(!IsOperXline(source_p))
{ {
@ -152,8 +154,11 @@ mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char
if(!match(target_server, me.name)) if(!match(target_server, me.name))
return 0; return 0;
/* Set as local-only. */
propagated = 0;
} }
else if(rb_dlink_list_length(&cluster_conf_list) > 0) else if(!propagated && rb_dlink_list_length(&cluster_conf_list) > 0)
cluster_xline(source_p, temp_time, name, reason); cluster_xline(source_p, temp_time, name, reason);
if((aconf = find_xline_mask(name)) != NULL) if((aconf = find_xline_mask(name)) != NULL)
@ -166,7 +171,13 @@ mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char
if(!valid_xline(source_p, name, reason)) if(!valid_xline(source_p, name, reason))
return 0; return 0;
apply_xline(source_p, name, reason, temp_time); if(propagated && temp_time == 0)
{
sendto_one_notice(source_p, ":Cannot set a permanent global ban");
return 0;
}
apply_xline(source_p, name, reason, temp_time, propagated);
return 0; return 0;
} }
@ -226,7 +237,7 @@ handle_remote_xline(struct Client *source_p, int temp_time, const char *name, co
return; return;
} }
apply_xline(source_p, name, reason, temp_time); apply_xline(source_p, name, reason, temp_time, 0);
} }
/* valid_xline() /* valid_xline()
@ -270,7 +281,7 @@ valid_xline(struct Client *source_p, const char *gecos, const char *reason)
} }
void void
apply_xline(struct Client *source_p, const char *name, const char *reason, int temp_time) apply_xline(struct Client *source_p, const char *name, const char *reason, int temp_time, int propagated)
{ {
struct ConfItem *aconf; struct ConfItem *aconf;
@ -283,7 +294,32 @@ apply_xline(struct Client *source_p, const char *name, const char *reason, int t
aconf->info.oper = operhash_add(get_oper_name(source_p)); aconf->info.oper = operhash_add(get_oper_name(source_p));
if(temp_time > 0) if(propagated)
{
aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY;
aconf->hold = rb_current_time() + temp_time;
aconf->lifetime = aconf->hold;
replace_old_ban(aconf);
rb_dlinkAddAlloc(aconf, &prop_bans);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s added global %d min. X-Line for [%s] [%s]",
get_oper_name(source_p), temp_time / 60,
aconf->host, reason);
ilog(L_KLINE, "X %s %d %s %s",
get_oper_name(source_p), temp_time / 60, name, reason);
sendto_one_notice(source_p, ":Added global %d min. X-Line [%s]",
temp_time / 60, aconf->host);
sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
":%s BAN X * %s %lu %d %d * :%s",
source_p->id, aconf->host,
(unsigned long)aconf->created,
(int)(aconf->hold - aconf->created),
(int)(aconf->lifetime - aconf->created),
reason);
}
else if(temp_time > 0)
{ {
aconf->hold = rb_current_time() + temp_time; aconf->hold = rb_current_time() + temp_time;
@ -366,6 +402,8 @@ cluster_xline(struct Client *source_p, int temp_time, const char *name, const ch
static int static int
mo_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) mo_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{ {
int propagated = 1;
if(!IsOperXline(source_p)) if(!IsOperXline(source_p))
{ {
sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "xline"); sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "xline");
@ -385,11 +423,12 @@ mo_unxline(struct Client *client_p, struct Client *source_p, int parc, const cha
if(match(parv[3], me.name) == 0) if(match(parv[3], me.name) == 0)
return 0; return 0;
}
else if(rb_dlink_list_length(&cluster_conf_list))
cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER, "%s", parv[1]);
remove_xline(source_p, parv[1]); propagated = 0;
}
/* cluster{} moved to remove_xline */
remove_xline(source_p, parv[1], propagated);
return 0; return 0;
} }
@ -434,13 +473,13 @@ handle_remote_unxline(struct Client *source_p, const char *name)
source_p->servptr->name, SHARED_UNXLINE)) source_p->servptr->name, SHARED_UNXLINE))
return; return;
remove_xline(source_p, name); remove_xline(source_p, name, 0);
return; return;
} }
static void static void
remove_xline(struct Client *source_p, const char *name) remove_xline(struct Client *source_p, const char *name, int propagated)
{ {
struct ConfItem *aconf; struct ConfItem *aconf;
rb_dlink_node *ptr; rb_dlink_node *ptr;
@ -451,6 +490,41 @@ remove_xline(struct Client *source_p, const char *name)
if(!irccmp(aconf->host, name)) if(!irccmp(aconf->host, name))
{ {
if(aconf->lifetime)
{
if(!propagated)
{
sendto_one_notice(source_p, ":Cannot remove global X-Line %s on specific servers", name);
return;
}
ptr = rb_dlinkFind(aconf, &prop_bans);
if(ptr == NULL)
return;
sendto_one_notice(source_p, ":X-Line for [%s] is removed", name);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s has removed the global X-Line for: [%s]",
get_oper_name(source_p), name);
ilog(L_KLINE, "UX %s %s", get_oper_name(source_p), name);
if(aconf->created < rb_current_time())
aconf->created = rb_current_time();
else
aconf->created++;
aconf->hold = aconf->created;
operhash_delete(aconf->info.oper);
aconf->info.oper = operhash_add(get_oper_name(source_p));
aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY;
sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
":%s BAN X * %s %lu %d %d * :*",
source_p->id, aconf->host,
(unsigned long)aconf->created,
0,
(int)(aconf->lifetime - aconf->created));
remove_reject_mask(aconf->host, NULL);
deactivate_conf(aconf, ptr);
return;
}
else if(propagated && rb_dlink_list_length(&cluster_conf_list))
cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER, "%s", name);
if(!aconf->hold) if(!aconf->hold)
{ {
bandb_del(BANDB_XLINE, aconf->host, NULL); bandb_del(BANDB_XLINE, aconf->host, NULL);
@ -477,6 +551,9 @@ remove_xline(struct Client *source_p, const char *name)
} }
} }
if(propagated && rb_dlink_list_length(&cluster_conf_list))
cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER, "%s", name);
sendto_one_notice(source_p, ":No X-Line for %s", name); sendto_one_notice(source_p, ":No X-Line for %s", name);
return; return;

View file

@ -1358,3 +1358,54 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
sendto_server(client_p, chptr, cap, nocap, "%s %s", modebuf, parabuf); sendto_server(client_p, chptr, cap, nocap, "%s %s", modebuf, parabuf);
} }
} }
void
resv_chan_forcepart(const char *name, const char *reason, int temp_time)
{
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
struct Channel *chptr;
struct membership *msptr;
struct Client *target_p;
if(!ConfigChannel.resv_forcepart)
return;
/* for each user on our server in the channel list
* send them a PART, and notify opers.
*/
chptr = find_channel(name);
if(chptr != NULL)
{
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
{
msptr = ptr->data;
target_p = msptr->client_p;
if(IsExemptResv(target_p))
continue;
sendto_server(target_p, chptr, CAP_TS6, NOCAPS,
":%s PART %s", target_p->id, chptr->chname);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
target_p->name, target_p->username,
target_p->host, chptr->chname, target_p->name);
remove_user_from_channel(msptr);
/* notify opers & user they were removed from the channel */
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Forced PART for %s!%s@%s from %s (%s)",
target_p->name, target_p->username,
target_p->host, name, reason);
if(temp_time > 0)
sendto_one_notice(target_p, ":*** Channel %s is temporarily unavailable on this server.",
name);
else
sendto_one_notice(target_p, ":*** Channel %s is no longer available on this server.",
name);
}
}
}

View file

@ -72,12 +72,11 @@ int chmode_flags[256];
/* OPTIMIZE ME! -- dwr */ /* OPTIMIZE ME! -- dwr */
void void
construct_noparam_modes(void) construct_cflags_strings(void)
{ {
int i; int i;
char *ptr = cflagsbuf; char *ptr = cflagsbuf;
char *ptr2 = cflagsmyinfo; char *ptr2 = cflagsmyinfo;
static int prev_chmode_flags[256];
*ptr = '\0'; *ptr = '\0';
*ptr2 = '\0'; *ptr2 = '\0';
@ -99,22 +98,6 @@ construct_noparam_modes(void)
chmode_flags[i] = 0; chmode_flags[i] = 0;
} }
if (prev_chmode_flags[i] != 0 && prev_chmode_flags[i] != chmode_flags[i])
{
if (chmode_flags[i] == 0)
{
chmode_table[i].set_func = chm_orphaned;
sendto_realops_snomask(SNO_DEBUG, L_ALL, "Cmode +%c is now orphaned", i);
}
else
{
sendto_realops_snomask(SNO_DEBUG, L_ALL, "Orphaned cmode +%c is picked up by module", i);
}
chmode_flags[i] = prev_chmode_flags[i];
}
else
prev_chmode_flags[i] = chmode_flags[i];
switch (chmode_flags[i]) switch (chmode_flags[i])
{ {
case MODE_EXLIMIT: case MODE_EXLIMIT:
@ -158,7 +141,7 @@ construct_noparam_modes(void)
* 0 if no cflags are available * 0 if no cflags are available
* side effects - NONE * side effects - NONE
*/ */
unsigned int static unsigned int
find_cflag_slot(void) find_cflag_slot(void)
{ {
unsigned int all_cflags = 0, my_cflag = 0, i; unsigned int all_cflags = 0, my_cflag = 0, i;
@ -172,6 +155,34 @@ find_cflag_slot(void)
return my_cflag; return my_cflag;
} }
unsigned int
cflag_add(char c_, ChannelModeFunc function)
{
int c = (unsigned char)c_;
if (chmode_table[c].set_func != chm_nosuch &&
chmode_table[c].set_func != chm_orphaned)
return 0;
if (chmode_table[c].set_func == chm_nosuch)
chmode_table[c].mode_type = find_cflag_slot();
if (chmode_table[c].mode_type == 0)
return 0;
chmode_table[c].set_func = function;
construct_cflags_strings();
return chmode_table[c].mode_type;
}
void
cflag_orphan(char c_)
{
int c = (unsigned char)c_;
s_assert(chmode_flags[c] != 0);
chmode_table[c].set_func = chm_orphaned;
construct_cflags_strings();
}
static int static int
get_channel_access(struct Client *source_p, struct membership *msptr) get_channel_access(struct Client *source_p, struct membership *msptr)
{ {

View file

@ -324,7 +324,10 @@ initialize_global_set_options(void)
splitchecking = 1; splitchecking = 1;
} }
GlobalSetOptions.ident_timeout = IDENT_TIMEOUT; if(ConfigFileEntry.default_ident_timeout)
GlobalSetOptions.ident_timeout = ConfigFileEntry.default_ident_timeout;
else
GlobalSetOptions.ident_timeout = IDENT_TIMEOUT;
rb_strlcpy(GlobalSetOptions.operstring, rb_strlcpy(GlobalSetOptions.operstring,
ConfigFileEntry.default_operstring, ConfigFileEntry.default_operstring,
@ -649,13 +652,7 @@ main(int argc, char *argv[])
init_monitor(); init_monitor();
init_isupport(); init_isupport();
/* noparam core modes have to be initialized before the module construct_cflags_strings();
* system is initialized, otherwise we have a table collision.
*
* modules call this after they are done initializing...
* --nenolod
*/
construct_noparam_modes();
load_all_modules(1); load_all_modules(1);
#ifndef STATIC_MODULES #ifndef STATIC_MODULES

View file

@ -2136,6 +2136,7 @@ static struct ConfEntry conf_general_table[] =
{ "collision_fnc", CF_YESNO, NULL, 0, &ConfigFileEntry.collision_fnc }, { "collision_fnc", CF_YESNO, NULL, 0, &ConfigFileEntry.collision_fnc },
{ "connect_timeout", CF_TIME, NULL, 0, &ConfigFileEntry.connect_timeout }, { "connect_timeout", CF_TIME, NULL, 0, &ConfigFileEntry.connect_timeout },
{ "default_floodcount", CF_INT, NULL, 0, &ConfigFileEntry.default_floodcount }, { "default_floodcount", CF_INT, NULL, 0, &ConfigFileEntry.default_floodcount },
{ "default_ident_timeout", CF_INT, NULL, 0, &ConfigFileEntry.default_ident_timeout },
{ "disable_auth", CF_YESNO, NULL, 0, &ConfigFileEntry.disable_auth }, { "disable_auth", CF_YESNO, NULL, 0, &ConfigFileEntry.disable_auth },
{ "dots_in_ident", CF_INT, NULL, 0, &ConfigFileEntry.dots_in_ident }, { "dots_in_ident", CF_INT, NULL, 0, &ConfigFileEntry.dots_in_ident },
{ "failed_oper_notice", CF_YESNO, NULL, 0, &ConfigFileEntry.failed_oper_notice }, { "failed_oper_notice", CF_YESNO, NULL, 0, &ConfigFileEntry.failed_oper_notice },
@ -2175,6 +2176,7 @@ static struct ConfEntry conf_general_table[] =
{ "ts_warn_delta", CF_TIME, NULL, 0, &ConfigFileEntry.ts_warn_delta }, { "ts_warn_delta", CF_TIME, NULL, 0, &ConfigFileEntry.ts_warn_delta },
{ "use_whois_actually", CF_YESNO, NULL, 0, &ConfigFileEntry.use_whois_actually }, { "use_whois_actually", CF_YESNO, NULL, 0, &ConfigFileEntry.use_whois_actually },
{ "warn_no_nline", CF_YESNO, NULL, 0, &ConfigFileEntry.warn_no_nline }, { "warn_no_nline", CF_YESNO, NULL, 0, &ConfigFileEntry.warn_no_nline },
{ "use_propagated_bans",CF_YESNO, NULL, 0, &ConfigFileEntry.use_propagated_bans },
{ "\0", 0, NULL, 0, NULL } { "\0", 0, NULL, 0, NULL }
}; };

View file

@ -744,6 +744,7 @@ set_default_conf(void)
ConfigFileEntry.collision_fnc = YES; ConfigFileEntry.collision_fnc = YES;
ConfigFileEntry.global_snotices = YES; ConfigFileEntry.global_snotices = YES;
ConfigFileEntry.operspy_dont_care_user_info = NO; ConfigFileEntry.operspy_dont_care_user_info = NO;
ConfigFileEntry.use_propagated_bans = YES;
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
ConfigFileEntry.compression_level = 4; ConfigFileEntry.compression_level = 4;
@ -781,6 +782,7 @@ set_default_conf(void)
ConfigFileEntry.min_nonwildcard = 4; ConfigFileEntry.min_nonwildcard = 4;
ConfigFileEntry.min_nonwildcard_simple = 3; ConfigFileEntry.min_nonwildcard_simple = 3;
ConfigFileEntry.default_floodcount = 8; ConfigFileEntry.default_floodcount = 8;
ConfigFileEntry.default_ident_timeout = 5;
ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT; ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
ConfigFileEntry.tkline_expire_notices = 0; ConfigFileEntry.tkline_expire_notices = 0;
@ -1063,6 +1065,36 @@ deactivate_conf(struct ConfItem *aconf, rb_dlink_node *ptr)
} }
} }
/* Given a new ban ConfItem, look for any matching ban, update the lifetime
* from it and delete it.
*/
void
replace_old_ban(struct ConfItem *aconf)
{
rb_dlink_node *ptr;
struct ConfItem *oldconf;
ptr = find_prop_ban(aconf->status, aconf->user, aconf->host);
if(ptr != NULL)
{
oldconf = ptr->data;
/* Remember at least as long as the old one. */
if(oldconf->lifetime > aconf->lifetime)
aconf->lifetime = oldconf->lifetime;
/* Force creation time to increase. */
if(oldconf->created >= aconf->created)
aconf->created = oldconf->created + 1;
/* Leave at least one second of validity. */
if(aconf->hold <= aconf->created)
aconf->hold = aconf->created + 1;
if(aconf->lifetime < aconf->hold)
aconf->lifetime = aconf->hold;
/* Tell deactivate_conf() to destroy it. */
oldconf->lifetime = rb_current_time();
deactivate_conf(oldconf, ptr);
}
}
static void static void
expire_prop_bans(void *list) expire_prop_bans(void *list)
{ {
@ -1230,7 +1262,7 @@ get_user_ban_reason(struct ConfItem *aconf)
rb_snprintf(reasonbuf, sizeof reasonbuf, rb_snprintf(reasonbuf, sizeof reasonbuf,
"Temporary %c-line %d min. - ", "Temporary %c-line %d min. - ",
aconf->status == CONF_DLINE ? 'D' : 'K', aconf->status == CONF_DLINE ? 'D' : 'K',
(aconf->hold - aconf->created) / 60); (int)((aconf->hold - aconf->created) / 60));
else else
reasonbuf[0] = '\0'; reasonbuf[0] = '\0';
if (aconf->passwd) if (aconf->passwd)