diff --git a/doc/example.conf b/doc/example.conf index 6a79129e..8c9dbf23 100755 --- a/doc/example.conf +++ b/doc/example.conf @@ -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; diff --git a/doc/reference.conf b/doc/reference.conf index 10971d4d..4c0e604b 100755 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -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; diff --git a/extensions/chm_adminonly.c b/extensions/chm_adminonly.c index 9380c3df..c478e91e 100644 --- a/extensions/chm_adminonly.c +++ b/extensions/chm_adminonly.c @@ -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; } diff --git a/extensions/chm_operonly.c b/extensions/chm_operonly.c index 4912e5a7..5cb87ab3 100644 --- a/extensions/chm_operonly.c +++ b/extensions/chm_operonly.c @@ -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; } diff --git a/extensions/chm_sslonly.c b/extensions/chm_sslonly.c index 197aac69..2808bb18 100644 --- a/extensions/chm_sslonly.c +++ b/extensions/chm_sslonly.c @@ -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; } diff --git a/help/opers/index b/help/opers/index index 673c1762..56171ec4 100644 --- a/help/opers/index +++ b/help/opers/index @@ -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 diff --git a/help/opers/modreload b/help/opers/modreload new file mode 100644 index 00000000..96abca29 --- /dev/null +++ b/help/opers/modreload @@ -0,0 +1,6 @@ +MODRELOAD + +-- Reload a module in the ircd +Use just the module name, the path is not needed. + +- Requires Oper Priv: A diff --git a/help/opers/stats b/help/opers/stats index 5d25900d..fb7bb347 100644 --- a/help/opers/stats +++ b/help/opers/stats @@ -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 diff --git a/include/channel.h b/include/channel.h index 090f7659..923871ed 100644 --- a/include/channel.h +++ b/include/channel.h @@ -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, diff --git a/include/chmode.h b/include/chmode.h index a9c04a64..f30c9bf3 100644 --- a/include/chmode.h +++ b/include/chmode.h @@ -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]; diff --git a/include/s_conf.h b/include/s_conf.h index 4cacc5e0..03e0d5fa 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -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); diff --git a/modules/core/m_ban.c b/modules/core/m_ban.c index f61ba076..d966edd4 100644 --- a/modules/core/m_ban.c +++ b/modules/core/m_ban.c @@ -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", diff --git a/modules/m_cap.c b/modules/m_cap.c index c5283a8c..bf929953 100644 --- a/modules/m_cap.c +++ b/modules/m_cap.c @@ -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, diff --git a/modules/m_info.c b/modules/m_info.c index d3ddb3b8..62d75f75 100644 --- a/modules/m_info.c +++ b/modules/m_info.c @@ -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, diff --git a/modules/m_kline.c b/modules/m_kline.c index 46ff7304..89ba2353 100644 --- a/modules/m_kline.c +++ b/modules/m_kline.c @@ -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); diff --git a/modules/m_resv.c b/modules/m_resv.c index 01b41b79..af727478 100644 --- a/modules/m_resv.c +++ b/modules/m_resv.c @@ -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); - } - } -} diff --git a/modules/m_xline.c b/modules/m_xline.c index 556ad005..d1975ecd 100644 --- a/modules/m_xline.c +++ b/modules/m_xline.c @@ -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; diff --git a/src/channel.c b/src/channel.c index 7483b6e5..1a159f14 100644 --- a/src/channel.c +++ b/src/channel.c @@ -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); + } + } +} diff --git a/src/chmode.c b/src/chmode.c index d4e284c4..ea0613ba 100644 --- a/src/chmode.c +++ b/src/chmode.c @@ -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) { diff --git a/src/ircd.c b/src/ircd.c index 8577081b..b5f8076a 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -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 diff --git a/src/newconf.c b/src/newconf.c index 24749a83..1769d35d 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -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 } }; diff --git a/src/s_conf.c b/src/s_conf.c index 946380db..d8808c70 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -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)