#include "stdinc.h"
#include "send.h"
+#include "channel.h"
#include "client.h"
#include "common.h"
#include "config.h"
time_t created, hold, lifetime;
char *p;
int act;
+ int valid;
if (strlen(parv[1]) != 1)
{
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",
ptr = find_prop_ban(ntype, parv[2], parv[3]);
if (ptr != NULL)
{
+ /* We already know about this ban mask. */
aconf = ptr->data;
if (aconf->created > created ||
(aconf->created == created &&
aconf->host);
return 0;
}
+ /* act indicates if something happened (from the oper's
+ * point of view). This is the case if the ban was
+ * previously active (not deleted) or if the new ban
+ * is not a removal and not already expired.
+ */
act = !(aconf->status & CONF_ILLEGAL) || (hold != created &&
hold > rb_current_time());
if (lifetime > aconf->lifetime)
/* already expired, hmm */
if (aconf->lifetime <= rb_current_time())
return 0;
+ /* Deactivate, it will be reactivated later if appropriate. */
deactivate_conf(aconf, ptr);
rb_free(aconf->user);
aconf->user = NULL;
}
else
{
+ /* New ban mask. */
aconf = make_conf();
aconf->status = CONF_ILLEGAL | ntype;
aconf->lifetime = lifetime;
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)))
+ /* The ban is fully filled in and in the prop_bans list
+ * but still deactivated. Now determine if it should be activated
+ * and send the server notices.
+ */
+ /* We only reject *@* and the like here.
+ * Otherwise malformed bans are fairly harmless and can be removed.
+ */
+ 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 " : "",
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] : "",
parv[parc - 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,
+ (int)((hold - rb_current_time()) / 60),
aconf->user ? aconf->user : "",
aconf->user ? " " : "",
aconf->host,
aconf->user ? " " : "",
aconf->host);
}
+ /* If CONF_ILLEGAL is still set at this point, remove entries from the
+ * reject cache (for klines and xlines).
+ * If CONF_ILLEGAL is not set, add the ban to the type-specific data
+ * structure and take action on matched clients/channels.
+ */
switch (ntype)
{
case CONF_KILL:
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",