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";
non_redundant_klines = yes;
warn_no_nline = yes;
use_propagated_bans = yes;
stats_e_disabled = no;
stats_c_oper_only=no;
stats_h_oper_only=no;
@ -474,6 +475,7 @@ general {
short_motd = no;
ping_cookie = no;
connect_timeout = 30 seconds;
default_ident_timeout = 5;
disable_auth = no;
no_oper_flood = yes;
max_targets = 4;

View file

@ -1030,6 +1030,13 @@ general {
*/
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
* exempted and you dont want them listing on irc.
*/
@ -1109,6 +1116,11 @@ general {
*/
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 = no;

View file

@ -17,13 +17,14 @@ mapi_hfn_list_av1 adminonly_hfnlist[] = {
{ NULL, NULL }
};
static unsigned int mymode;
static int
_modinit(void)
{
chmode_table['A'].mode_type = find_cflag_slot();
chmode_table['A'].set_func = chm_staff;
construct_noparam_modes();
mymode = cflag_add('A', chm_staff);
if (mymode == 0)
return -1;
return 0;
}
@ -31,9 +32,7 @@ _modinit(void)
static void
_moddeinit(void)
{
chmode_table['A'].mode_type = 0;
construct_noparam_modes();
cflag_orphan('A');
}
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 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);
data->approved = ERR_CUSTOM;
}

View file

@ -17,7 +17,7 @@ mapi_hfn_list_av1 operonly_hfnlist[] = {
{ NULL, NULL }
};
static unsigned int mymode;
/* This is a simple example of how to use dynamic channel modes.
* Not tested enough yet, use at own risk.
@ -26,27 +26,18 @@ mapi_hfn_list_av1 operonly_hfnlist[] = {
static int
_modinit(void)
{
/* add the channel mode to the available slot */
chmode_table['O'].mode_type = find_cflag_slot();
chmode_table['O'].set_func = chm_staff;
construct_noparam_modes();
mymode = cflag_add('O', chm_staff);
if (mymode == 0)
return -1;
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
_moddeinit(void)
{
/* disable the channel mode and remove it from the available list */
chmode_table['O'].mode_type = 0;
construct_noparam_modes();
cflag_orphan('O');
}
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 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);
data->approved = ERR_CUSTOM;
}

View file

@ -17,13 +17,14 @@ mapi_hfn_list_av1 sslonly_hfnlist[] = {
{ NULL, NULL }
};
static unsigned int mymode;
static int
_modinit(void)
{
chmode_table['S'].mode_type = find_cflag_slot();
chmode_table['S'].set_func = chm_simple;
construct_noparam_modes();
mymode = cflag_add('S', chm_simple);
if (mymode == 0)
return -1;
return 0;
}
@ -32,9 +33,7 @@ _modinit(void)
static void
_moddeinit(void)
{
chmode_table['S'].mode_type = 0;
construct_noparam_modes();
cflag_orphan('S');
}
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 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!");
data->approved = ERR_CUSTOM;
}

View file

@ -8,16 +8,16 @@ HELP INDEX INFO INVITE
ISON JOIN KICK KILL
KLINE KNOCK LINKS LIST
LOCOPS LUSERS MAP MASKTRACE
MODLIST MODLOAD MODRESTART MODUNLOAD
MOTD NAMES NICK NOTICE
OPER OPERSPY OPERWALL PART
PASS PING PONG POST
PRIVMSG QUIT REHASH RESTART
RESV SCAN SERVER SET
SJOIN SNOMASK SQUIT STATS
SVINFO TESTGECOS TESTLINE TESTMASK
TIME TOPIC TRACE UHELP
UMODE UNDLINE UNKLINE UNREJECT
UNRESV UNXLINE USER USERHOST
USERS VERSION WALLOPS WHO
WHOIS WHOWAS XLINE
MODLIST MODLOAD MODRELOAD MODRESTART
MODUNLOAD MOTD NAMES NICK
NOTICE OPER OPERSPY OPERWALL
PART PASS PING PONG
POST PRIVMSG QUIT REHASH
RESTART RESV SCAN SERVER
SET SJOIN SNOMASK SQUIT
STATS SVINFO TESTGECOS TESTLINE
TESTMASK TIME TOPIC TRACE
UHELP UMODE UNDLINE UNKLINE
UNREJECT UNRESV UNXLINE USER
USERHOST USERS VERSION WALLOPS
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)
^ P - Shows configured ports
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
* r - Shows resource usage by ircd
* t - Shows generic server stats
* U - Shows shared blocks (Old U: lines)
u - Shows server uptime
^ 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)
^ y - Shows connection classes (Old Y: lines)
* z - Shows memory stats

View file

@ -126,11 +126,13 @@ struct ChCapCombo
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
{
void (*set_func) (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);
ChannelModeFunc set_func;
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,
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,
struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]);
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,
const char **parv, int *errors, int dir, char c, long mode_type);
extern void construct_noparam_modes(void);
extern void find_orphaned_cflags(void);
extern unsigned int find_cflag_slot(void);
extern unsigned int cflag_add(char c, ChannelModeFunc function);
extern void cflag_orphan(char c);
extern void construct_cflags_strings(void);
extern char cflagsbuf[256];
extern char cflagsmyinfo[256];

View file

@ -206,6 +206,7 @@ struct config_file_entry
int min_nonwildcard_simple;
int default_floodcount;
int client_flood;
int default_ident_timeout;
int use_egd;
int ping_cookie;
int tkline_expire_notices;
@ -223,6 +224,7 @@ struct config_file_entry
int default_umodes;
int global_snotices;
int operspy_dont_care_user_info;
int use_propagated_bans;
};
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 void deactivate_conf(struct ConfItem *, rb_dlink_node *);
extern void replace_old_ban(struct ConfItem *);
extern void read_conf_files(int cold);

View file

@ -29,6 +29,7 @@
#include "stdinc.h"
#include "send.h"
#include "channel.h"
#include "client.h"
#include "common.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;
char *p;
int act;
int valid;
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;
stype = "K-Line";
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:
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"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->created = created;
aconf->hold = hold;
p = strchr(parv[parc - 1], '|');
if (p == NULL)
if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL)
aconf->passwd = rb_strdup(parv[parc - 1]);
else
{
aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1);
aconf->spasswd = rb_strdup(p + 1);
}
if (act && hold != created &&
!(ntype == CONF_KILL ?
valid_wild_card(aconf->user, aconf->host) :
valid_wild_card_simple(aconf->host)))
switch (ntype)
{
case CONF_KILL:
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,
"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,
IsServer(source_p) ? source_p->name : get_oper_name(source_p),
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,
"%s added global %d min. %s%s%s for [%s%s%s] [%s]",
IsServer(source_p) ? source_p->name : get_oper_name(source_p),
(hold - rb_current_time()) / 60,
(int)((hold - rb_current_time()) / 60),
stype,
strcmp(parv[7], "*") ? " from " : "",
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->host,
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),
(hold - rb_current_time()) / 60,
aconf->user, aconf->host,
(int)((hold - rb_current_time()) / 60),
aconf->user ? aconf->user : "",
aconf->user ? " " : "",
aconf->host,
parv[parc - 1]);
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,
strcmp(parv[7], "*") ? " on behalf of " : "",
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),
aconf->user, aconf->host);
aconf->user ? aconf->user : "",
aconf->user ? " " : "",
aconf->host);
}
switch (ntype)
{
@ -244,6 +267,26 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
check_klines();
}
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,
":%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;
int buflen = 0;
int curlen, mlen;
int i;
size_t i;
mlen = rb_sprintf(buf, ":%s CAP %s %s",
me.name,

View file

@ -133,6 +133,12 @@ static struct InfoStruct info_table[] = {
&ConfigFileEntry.connect_timeout,
"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",
OUTPUT_DECIMAL,
@ -482,6 +488,12 @@ static struct InfoStruct info_table[] = {
&ConfigFileEntry.warn_no_nline,
"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",
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;
int tkline_time = 0;
int loc = 1;
int propagated = 1;
int propagated = ConfigFileEntry.use_propagated_bans;
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 "
"characters with the user@host",
ConfigFileEntry.min_nonwildcard);
return 0;
return;
}
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,
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->hold = rb_current_time() + tkline_time;
aconf->lifetime = aconf->hold;
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);
}
replace_old_ban(aconf);
rb_dlinkAddAlloc(aconf, &prop_bans);
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$");
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,
int temp_time, const char *name, const char *reason);
static void cluster_resv(struct Client *source_p, int temp_time,
const char *name, const char *reason);
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 resv_chan_forcepart(const char *name, const char *reason, int temp_time);
static void remove_resv(struct Client *source_p, const char *name, int propagated);
/*
* 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;
int temp_time;
int loc = 1;
int propagated = ConfigFileEntry.use_propagated_bans;
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];
loc += 2;
/* Set as local-only. */
propagated = 0;
}
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)
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);
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;
}
@ -161,7 +170,7 @@ ms_resv(struct Client *client_p, struct Client *source_p, int parc, const char *
if(!IsPerson(source_p))
return 0;
parse_resv(source_p, parv[2], parv[3], 0);
parse_resv(source_p, parv[2], parv[3], 0, 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))
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;
}
@ -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
*/
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;
@ -223,10 +232,32 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
aconf->host = rb_strdup(name);
aconf->passwd = rb_strdup(reason);
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;
@ -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);
}
add_to_resv_hash(aconf->host, aconf);
resv_chan_forcepart(aconf->host, aconf->passwd, temp_time);
}
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->passwd = rb_strdup(reason);
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;
@ -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);
}
rb_dlinkAddAlloc(aconf, &resv_conf_list);
}
else
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
mo_unresv(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
int propagated = 1;
if(!IsOperResv(source_p))
{
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)
return 0;
propagated = 0;
}
#if 0
else if(rb_dlink_list_length(&cluster_conf_list) > 0)
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;
}
@ -448,24 +514,63 @@ handle_remote_unresv(struct Client *source_p, const char *name)
source_p->servptr->name, SHARED_UNRESV))
return;
remove_resv(source_p, name);
remove_resv(source_p, name, 0);
return;
}
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;
rb_dlink_node *ptr;
if(IsChannelName(name))
{
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);
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);
ilog(L_KLINE, "UR %s %s", get_oper_name(source_p), name);
if(!aconf->hold)
@ -485,8 +590,6 @@ remove_resv(struct Client *source_p, const char *name)
}
else
{
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, resv_conf_list.head)
{
aconf = ptr->data;
@ -499,19 +602,62 @@ remove_resv(struct Client *source_p, const char *name)
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);
return;
}
if(!aconf->hold)
bandb_del(BANDB_RESV, aconf->host, NULL);
else
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);
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,
"%s has removed the RESV for: [%s]",
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.. */
rb_dlinkDestroy(ptr, &resv_conf_list);
@ -520,54 +666,3 @@ remove_resv(struct Client *source_p, const char *name)
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 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,
int temp_time, const char *name, const char *type, const char *reason);
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);
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()
@ -107,6 +108,7 @@ mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char
const char *target_server = NULL;
int temp_time;
int loc = 1;
int propagated = ConfigFileEntry.use_propagated_bans;
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))
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);
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))
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;
}
@ -226,7 +237,7 @@ handle_remote_xline(struct Client *source_p, int temp_time, const char *name, co
return;
}
apply_xline(source_p, name, reason, temp_time);
apply_xline(source_p, name, reason, temp_time, 0);
}
/* valid_xline()
@ -270,7 +281,7 @@ valid_xline(struct Client *source_p, const char *gecos, const char *reason)
}
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;
@ -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));
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;
@ -366,6 +402,8 @@ cluster_xline(struct Client *source_p, int temp_time, const char *name, const ch
static int
mo_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
int propagated = 1;
if(!IsOperXline(source_p))
{
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)
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;
}
@ -434,13 +473,13 @@ handle_remote_unxline(struct Client *source_p, const char *name)
source_p->servptr->name, SHARED_UNXLINE))
return;
remove_xline(source_p, name);
remove_xline(source_p, name, 0);
return;
}
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;
rb_dlink_node *ptr;
@ -451,6 +490,41 @@ remove_xline(struct Client *source_p, const char *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)
{
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);
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);
}
}
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 */
void
construct_noparam_modes(void)
construct_cflags_strings(void)
{
int i;
char *ptr = cflagsbuf;
char *ptr2 = cflagsmyinfo;
static int prev_chmode_flags[256];
*ptr = '\0';
*ptr2 = '\0';
@ -99,22 +98,6 @@ construct_noparam_modes(void)
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])
{
case MODE_EXLIMIT:
@ -158,7 +141,7 @@ construct_noparam_modes(void)
* 0 if no cflags are available
* side effects - NONE
*/
unsigned int
static unsigned int
find_cflag_slot(void)
{
unsigned int all_cflags = 0, my_cflag = 0, i;
@ -172,6 +155,34 @@ find_cflag_slot(void)
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
get_channel_access(struct Client *source_p, struct membership *msptr)
{

View file

@ -324,7 +324,10 @@ initialize_global_set_options(void)
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,
ConfigFileEntry.default_operstring,
@ -649,13 +652,7 @@ main(int argc, char *argv[])
init_monitor();
init_isupport();
/* noparam core modes have to be initialized before the module
* system is initialized, otherwise we have a table collision.
*
* modules call this after they are done initializing...
* --nenolod
*/
construct_noparam_modes();
construct_cflags_strings();
load_all_modules(1);
#ifndef STATIC_MODULES

View file

@ -2136,6 +2136,7 @@ static struct ConfEntry conf_general_table[] =
{ "collision_fnc", CF_YESNO, NULL, 0, &ConfigFileEntry.collision_fnc },
{ "connect_timeout", CF_TIME, NULL, 0, &ConfigFileEntry.connect_timeout },
{ "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 },
{ "dots_in_ident", CF_INT, NULL, 0, &ConfigFileEntry.dots_in_ident },
{ "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 },
{ "use_whois_actually", CF_YESNO, NULL, 0, &ConfigFileEntry.use_whois_actually },
{ "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 }
};

View file

@ -744,6 +744,7 @@ set_default_conf(void)
ConfigFileEntry.collision_fnc = YES;
ConfigFileEntry.global_snotices = YES;
ConfigFileEntry.operspy_dont_care_user_info = NO;
ConfigFileEntry.use_propagated_bans = YES;
#ifdef HAVE_LIBZ
ConfigFileEntry.compression_level = 4;
@ -781,6 +782,7 @@ set_default_conf(void)
ConfigFileEntry.min_nonwildcard = 4;
ConfigFileEntry.min_nonwildcard_simple = 3;
ConfigFileEntry.default_floodcount = 8;
ConfigFileEntry.default_ident_timeout = 5;
ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
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
expire_prop_bans(void *list)
{
@ -1230,7 +1262,7 @@ get_user_ban_reason(struct ConfItem *aconf)
rb_snprintf(reasonbuf, sizeof reasonbuf,
"Temporary %c-line %d min. - ",
aconf->status == CONF_DLINE ? 'D' : 'K',
(aconf->hold - aconf->created) / 60);
(int)((aconf->hold - aconf->created) / 60));
else
reasonbuf[0] = '\0';
if (aconf->passwd)