Automated merge with ssh://shadowircd/uranium/shadowircd/

This commit is contained in:
B.Greenham 2010-03-27 22:42:54 -04:00
commit 0068a2a2e2
42 changed files with 1440 additions and 265 deletions

View File

@ -10,6 +10,8 @@ Makefile
.deps
.libs
autom4te.cache
bandb/bandb
bandb/bantool
config.log
config.status
include/setup.h
@ -18,6 +20,7 @@ libratbox/include/librb-config.h
libratbox/include/stamp-h1
libratbox/libratbox.pc
libratbox/libtool
libratbox/src/version.c
scripts/*.tbz2
scripts/*.tgz
servlink/servlink

View File

@ -17,8 +17,6 @@ network configurations.
The charybdis core team is listed in nick-alphabetical order:
dwr, Valery Yatsko <dwr -at- shadowircd.net>
gxti, Michael Tharp <gxti -at- partiallystapled.com>
jilles, Jilles Tjoelker <jilles -at- stack.nl>
nenolod, William Pitcock <nenolod -at- nenolod.net>
@ -28,7 +26,9 @@ in nick-alphabetical order:
AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
anfl, Lee Hardy <lee -at- leeh.co.uk>
beu, Elfyn McBratney <elfyn.mcbratney -at- gmail.com>
dwr, Valery Yatsko <dwr -at- shadowircd.net>
Entrope, Michael Poole <mdpoole -at- trolius.org>
gxti, Michael Tharp <gxti -at- partiallystapled.com>
spb, Stephen Bennett <spb -at- attenuate.org>
ThaPrince, Jon Christopherson <jon -at- vile.com>
twincest, River Tarnell <river -at- attenuate.org>

View File

@ -38,6 +38,8 @@
#define MAXPARA 10
#define COMMIT_INTERVAL 3 /* seconds */
typedef enum
{
BANDB_KLINE,
@ -57,9 +59,17 @@ static const char *bandb_table[LAST_BANDB_TYPE] = {
static rb_helper *bandb_helper;
static int in_transaction;
static void check_schema(void);
static void
bandb_commit(void *unused)
{
rsdb_transaction(RSDB_TRANS_END);
in_transaction = 0;
}
static void
parse_ban(bandb_type type, char *parv[], int parc)
{
@ -89,6 +99,14 @@ parse_ban(bandb_type type, char *parv[], int parc)
perm = parv[para++];
reason = parv[para++];
if(!in_transaction)
{
rsdb_transaction(RSDB_TRANS_START);
in_transaction = 1;
rb_event_addonce("bandb_commit", bandb_commit, NULL,
COMMIT_INTERVAL);
}
rsdb_exec(NULL,
"INSERT INTO %s (mask1, mask2, oper, time, perm, reason) VALUES('%Q', '%Q', '%Q', %s, %s, '%Q')",
bandb_table[type], mask1, mask2 ? mask2 : "", oper, curtime, perm, reason);
@ -113,6 +131,14 @@ parse_unban(bandb_type type, char *parv[], int parc)
if(type == BANDB_KLINE)
mask2 = parv[2];
if(!in_transaction)
{
rsdb_transaction(RSDB_TRANS_START);
in_transaction = 1;
rb_event_addonce("bandb_commit", bandb_commit, NULL,
COMMIT_INTERVAL);
}
rsdb_exec(NULL, "DELETE FROM %s WHERE mask1='%Q' AND mask2='%Q'",
bandb_table[type], mask1, mask2 ? mask2 : "");
}
@ -215,6 +241,8 @@ parse_request(rb_helper *helper)
static void
error_cb(rb_helper *helper)
{
if(in_transaction)
rsdb_transaction(RSDB_TRANS_END);
exit(1);
}

View File

@ -530,6 +530,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;

View File

@ -1198,6 +1198,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.
*/

View File

@ -55,10 +55,10 @@ send its own PASS, CAPAB and SERVER messages, followed by SVINFO and the burst.
Upon receiving the SERVER, the initiator will send SVINFO and the burst. If
ziplinks are used, SVINFO is the first compressed message.
The burst consists of SID and SERVER messages for all known servers, UID or
EUID messages for all known users (possibly followed by ENCAP REALHOST, ENCAP
LOGIN and/or AWAY) and SJOIN messages for all known channels (possibly followed
by BMASK and/or TB).
The burst consists of SID and SERVER messages for all known servers, BAN
messages for all propagated bans, UID or EUID messages for all known users
(possibly followed by ENCAP REALHOST, ENCAP LOGIN and/or AWAY) and SJOIN
messages for all known channels (possibly followed by BMASK and/or TB).
user modes:
(all)
@ -148,6 +148,43 @@ Otherwise, mark the user as away.
Changing away reason from one non-empty string to another non-empty string
may not be propagated.
BAN
charybdis TS6
capab: BAN
source: any
propagation: broadcast (restricted)
parameters: type, user mask, host mask, creation TS, duration, lifetime, oper, reason
Propagates a network wide ban.
The type is K for K:lines; other types are reserved.
The creation TS indicates when this ban was last modified. An incoming ban MUST
be ignored and not propagated if the creation TS is older than the creation TS
of the current ban. If the ban is identical, it SHOULD NOT be propagated to
avoid unnecessary network traffic. (Two changes to bans that set the TS to the
same value may cause desynchronization.)
The duration is 0 for an unban and relative to the creation TS for a ban.
When the duration has passed, the ban is no longer active but it may still
be necessary to remember it.
The lifetime is relative to the creation TS and indicates for how long this
ban needs to be remembered and propagated. This MUST be at least the duration.
Initially, it is usually set the same as the duration but when the ban is
modified later, it SHOULD be set such that the modified ban is remembered at
least as long as the original ban. This ensures that the original ban does not
revive via split servers. This requirement is only a SHOULD to allow for
implementations that only inject bans and do not remember any; implementations
that remember and propagate bans MUST set the lifetime appropriately.
The oper field indicates the oper that originally set the ban. If this message
is the initial propagation of a change, it SHOULD be sent as * (an asterisk).
The reason field indicates the reason for the ban. Any part after a | (vertical
bar) MUST NOT be shown to normal users. The rest of the field and the creation
TS and duration MAY be shown to normal users.
BMASK
source: server
propagation: broadcast

View File

@ -91,7 +91,7 @@ mr_webirc(struct Client *client_p, struct Client *source_p, int parc, const char
client_p->localClient->ip.ss_family, NULL);
if (aconf == NULL || !(aconf->status & CONF_CLIENT))
return 0;
if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->name, "webirc."))
if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc."))
{
/* XXX */
sendto_one(source_p, "NOTICE * :Not a CGI:IRC auth block");

View File

@ -16,6 +16,7 @@ X B - Shows hash statistics
* e - Shows exemptions to D lines
X E - Shows Events
X f - Shows File Descriptors
* g - Shows global K lines
^ h - Shows hub_mask/leaf_mask (Old H:/L: lines)
^ i - Shows auth blocks (Old I: lines)
^ K - Shows K lines (or matched klines)
@ -28,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

@ -277,6 +277,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[]);

View File

@ -61,7 +61,7 @@ extern void inotice(const char *fmt, ...) AFP(1, 2);
extern void iwarn(const char *fmt, ...) AFP(1, 2);
extern void ierror(const char *fmt, ...) AFP(1, 2);
extern void report_operspy(struct Client *, const char *, const char *);
extern const char *smalldate(void);
extern const char *smalldate(time_t);
extern void ilog_error(const char *);
#endif

View File

@ -364,6 +364,9 @@ extern const char *form_str(int);
#define RPL_NOTESTLINE 726
#define RPL_TESTMASKGECOS 727
#define RPL_QUIETLIST 728
#define RPL_ENDOFQUIETLIST 729
#define RPL_MONONLINE 730
#define RPL_MONOFFLINE 731
#define RPL_MONLIST 732

9
include/operhash.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef INCLUDED_operhash_h
#define INCLUDED_operhash_h
void init_operhash(void);
const char *operhash_add(const char *name);
const char *operhash_find(const char *name);
void operhash_delete(const char *name);
#endif

View File

@ -56,11 +56,14 @@ extern char conf_line_in[256];
struct ConfItem
{
struct ConfItem *next; /* list node pointer */
unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
unsigned int flags;
int clients; /* Number of *LOCAL* clients using this */
char *name; /* IRC name, nick, server name, or original u@h */
union
{
char *name; /* IRC name, nick, server name, or original u@h */
const char *oper;
} info;
char *host; /* host part of user@host */
char *passwd; /* doubles as kline reason *ugh* */
char *spasswd; /* Password to send. */
@ -69,6 +72,8 @@ struct ConfItem
char *user; /* user part of user@host */
int port;
time_t hold; /* Hold action until this time (calendar time) */
time_t created; /* Creation time (for klines etc) */
time_t lifetime; /* Propagated lines: remember until this time */
char *className; /* Name of class */
struct Class *c_class; /* Class of connection */
rb_patricia_node_t *pnode; /* Our patricia node */
@ -92,6 +97,7 @@ struct ConfItem
/* Generic flags... */
#define CONF_FLAGS_TEMPORARY 0x00800000
#define CONF_FLAGS_NEED_SSL 0x00000002
#define CONF_FLAGS_MYOPER 0x00080000 /* need to rewrite info.oper on burst */
/* auth{} flags... */
#define CONF_FLAGS_NO_TILDE 0x00000004
#define CONF_FLAGS_NEED_IDENTD 0x00000008
@ -111,6 +117,9 @@ struct ConfItem
/* Macros for struct ConfItem */
#define IsConfBan(x) ((x)->status & (CONF_KILL|CONF_XLINE|CONF_DLINE|\
CONF_RESV_CHANNEL|CONF_RESV_NICK))
#define IsNoTilde(x) ((x)->flags & CONF_FLAGS_NO_TILDE)
#define IsNeedIdentd(x) ((x)->flags & CONF_FLAGS_NEED_IDENTD)
#define IsConfExemptKline(x) ((x)->flags & CONF_FLAGS_EXEMPTKLINE)
@ -220,6 +229,7 @@ struct config_file_entry
int default_umodes;
int global_snotices;
int operspy_dont_care_user_info;
int use_propagated_bans;
int secret_channels_in_whois;
int expire_override_time;
};
@ -320,6 +330,8 @@ extern struct admin_info AdminInfo; /* defined in ircd.c */
extern rb_dlink_list service_list;
extern rb_dlink_list prop_bans;
typedef enum temp_list
{
TEMP_MIN,
@ -337,6 +349,10 @@ extern void init_s_conf(void);
extern struct ConfItem *make_conf(void);
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);
extern int attach_conf(struct Client *, struct ConfItem *);
@ -348,6 +364,7 @@ extern struct ConfItem *find_tkline(const char *, const char *, struct sockaddr
extern char *show_iline_prefix(struct Client *, struct ConfItem *, char *);
extern void get_printable_conf(struct ConfItem *,
char **, char **, char **, char **, int *, char **);
extern char *get_user_ban_reason(struct ConfItem *aconf);
extern void get_printable_kline(struct Client *, struct ConfItem *,
char **, char **, char **, char **);
@ -355,6 +372,7 @@ extern void yyerror(const char *);
extern int conf_yy_fatal_error(const char *);
extern int conf_fgets(char *, int, FILE *);
extern int valid_wild_card(const char *, const char *);
extern void add_temp_kline(struct ConfItem *);
extern void add_temp_dline(struct ConfItem *);
extern void report_temp_klines(struct Client *);

View File

@ -72,12 +72,14 @@ struct Capability
#define CAP_SAVE 0x40000 /* supports SAVE (nick collision FNC) */
#define CAP_EUID 0x80000 /* supports EUID (ext UID + nonencap CHGHOST) */
#define CAP_EOPMOD 0x100000 /* supports EOPMOD (ext +z + ext topic) */
#define CAP_BAN 0x200000 /* supports propagated bans */
#define CAP_MASK (CAP_QS | CAP_EX | CAP_CHW | \
CAP_IE | CAP_KLN | CAP_SERVICE |\
CAP_CLUSTER | CAP_ENCAP | \
CAP_ZIP | CAP_KNOCK | CAP_UNKLN | \
CAP_RSFNC | CAP_SAVE | CAP_EUID | CAP_EOPMOD)
CAP_RSFNC | CAP_SAVE | CAP_EUID | CAP_EOPMOD | \
CAP_BAN)
#ifdef HAVE_LIBZ
#define CAP_ZIP_SUPPORTED CAP_ZIP

View File

@ -492,11 +492,14 @@ rb_bh_usage(rb_bh *bh, size_t *bused, size_t *bfree, size_t *bmemusage, const ch
if(desc != NULL)
*desc = bh->desc;
#else
static char *noballoc = "no blockheap";
*bused = 0;
*bfree = 0;
*bmemusage = 0;
*desc = noballoc;
if(bused != NULL)
*bused = 0;
if(bfree != NULL)
*bfree = 0;
if(bmemusage != NULL)
*bmemusage = 0;
if(desc != NULL)
*desc = "no blockheap";
#endif
}

View File

@ -28,9 +28,7 @@
#include <ratbox_lib.h>
#include <commio-int.h>
#ifndef NOBALLOC
static rb_bh *rb_linebuf_heap;
#endif
static int bufline_count = 0;

View File

@ -36,6 +36,7 @@ INCLUDES = -I../include -I../libratbox/include $(SSL_INCLUDES)
CPPFLAGS = ${INCLUDES} @CPPFLAGS@
CORE_SRCS = \
core/m_ban.c \
core/m_die.c \
core/m_error.c \
core/m_join.c \

303
modules/core/m_ban.c Normal file
View File

@ -0,0 +1,303 @@
/*
* charybdis: An advanced ircd.
* m_ban.c: Propagates network bans across servers.
*
* Copyright (C) 2010 Jilles Tjoelker
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "stdinc.h"
#include "send.h"
#include "channel.h"
#include "client.h"
#include "common.h"
#include "config.h"
#include "ircd.h"
#include "match.h"
#include "s_conf.h"
#include "s_newconf.h"
#include "msg.h"
#include "modules.h"
#include "hash.h"
#include "s_serv.h"
#include "operhash.h"
#include "reject.h"
#include "hostmask.h"
static int ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
struct Message ban_msgtab = {
"BAN", 0, 0, 0, MFLG_SLOW,
{mg_unreg, mg_ignore, {ms_ban, 9}, {ms_ban, 9}, mg_ignore, mg_ignore}
};
mapi_clist_av1 ban_clist[] = { &ban_msgtab, NULL };
DECLARE_MODULE_AV1(ban, NULL, NULL, ban_clist, NULL, NULL, "$Revision: 1349 $");
/* ms_ban()
*
* parv[1] - type
* parv[2] - username mask or *
* parv[3] - hostname mask
* parv[4] - creation TS
* parv[5] - duration (relative to creation)
* parv[6] - lifetime (relative to creation)
* parv[7] - oper or *
* parv[8] - reason (possibly with |operreason)
*/
static int
ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
rb_dlink_node *ptr;
struct ConfItem *aconf;
unsigned int ntype;
const char *oper, *stype;
time_t created, hold, lifetime;
char *p;
int act;
int valid;
if (strlen(parv[1]) != 1)
{
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"Unknown BAN type %s from %s",
parv[1], source_p->name);
return 0;
}
switch (parv[1][0])
{
case 'K':
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",
parv[1], source_p->name);
return 0;
}
created = atol(parv[4]);
hold = created + atoi(parv[5]);
lifetime = created + atoi(parv[6]);
if (!strcmp(parv[7], "*"))
oper = IsServer(source_p) ? source_p->name : get_oper_name(source_p);
else
oper = parv[7];
ptr = find_prop_ban(ntype, parv[2], parv[3]);
if (ptr != NULL)
{
aconf = ptr->data;
if (aconf->created > created ||
(aconf->created == created &&
aconf->lifetime >= lifetime))
{
if (IsPerson(source_p))
sendto_one_notice(source_p,
":Your %s [%s%s%s] has been superseded",
stype,
aconf->user ? aconf->user : "",
aconf->user ? "@" : "",
aconf->host);
return 0;
}
act = !(aconf->status & CONF_ILLEGAL) || (hold != created &&
hold > rb_current_time());
if (lifetime > aconf->lifetime)
aconf->lifetime = lifetime;
/* already expired, hmm */
if (aconf->lifetime <= rb_current_time())
return 0;
deactivate_conf(aconf, ptr);
rb_free(aconf->user);
aconf->user = NULL;
rb_free(aconf->host);
aconf->host = NULL;
operhash_delete(aconf->info.oper);
aconf->info.oper = NULL;
rb_free(aconf->passwd);
aconf->passwd = NULL;
rb_free(aconf->spasswd);
aconf->spasswd = NULL;
}
else
{
aconf = make_conf();
aconf->status = CONF_ILLEGAL | ntype;
aconf->lifetime = lifetime;
rb_dlinkAddAlloc(aconf, &prop_bans);
act = hold != created && hold > rb_current_time();
}
aconf->flags &= ~CONF_FLAGS_MYOPER;
aconf->flags |= CONF_FLAGS_TEMPORARY;
aconf->user = ntype == CONF_KILL ? rb_strdup(parv[2]) : NULL;
aconf->host = rb_strdup(parv[3]);
aconf->info.oper = operhash_add(oper);
aconf->created = created;
aconf->hold = hold;
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);
}
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",
(int)((hold - rb_current_time()) / 60),
stype,
IsServer(source_p) ? source_p->name : get_oper_name(source_p),
strcmp(parv[7], "*") ? " on behalf of " : "",
strcmp(parv[7], "*") ? parv[7] : "",
aconf->user ? aconf->user : "",
aconf->user ? "@" : "",
aconf->host);
if(IsPerson(source_p))
sendto_one_notice(source_p,
":Your %s [%s%s%s] has too few non-wildcard characters",
stype,
aconf->user ? aconf->user : "",
aconf->user ? "@" : "",
aconf->host);
/* Propagate it, but do not apply it locally. */
}
else if (act && hold != created)
{
/* Keep the notices in sync with modules/m_kline.c etc. */
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),
(int)((hold - rb_current_time()) / 60),
stype,
strcmp(parv[7], "*") ? " from " : "",
strcmp(parv[7], "*") ? parv[7] : "",
aconf->user ? aconf->user : "",
aconf->user ? "@" : "",
aconf->host,
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),
(int)((hold - rb_current_time()) / 60),
aconf->user ? aconf->user : "",
aconf->user ? " " : "",
aconf->host,
parv[parc - 1]);
aconf->status &= ~CONF_ILLEGAL;
}
else if (act)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s has removed the global %s for: [%s%s%s]%s%s",
IsServer(source_p) ? source_p->name : get_oper_name(source_p),
stype,
aconf->user ? aconf->user : "",
aconf->user ? "@" : "",
aconf->host,
strcmp(parv[7], "*") ? " on behalf of " : "",
strcmp(parv[7], "*") ? parv[7] : "");
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->user : "",
aconf->user ? " " : "",
aconf->host);
}
switch (ntype)
{
case CONF_KILL:
if (aconf->status & CONF_ILLEGAL)
remove_reject_mask(aconf->user, aconf->host);
else
{
add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
if(ConfigFileEntry.kline_delay ||
(IsServer(source_p) &&
!HasSentEob(source_p)))
{
if(kline_queued == 0)
{
rb_event_addonce("check_klines", check_klines_event, NULL,
ConfigFileEntry.kline_delay);
kline_queued = 1;
}
}
else
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",
source_p->id,
parv[1],
parv[2],
parv[3],
parv[4],
parv[5],
parv[6],
parv[7],
parv[parc - 1]);
return 0;
}

View File

@ -43,6 +43,7 @@
#include "parse.h"
#include "modules.h"
#include "bandbi.h"
#include "operhash.h"
static int mo_dline(struct Client *, struct Client *, int, const char **);
static int me_dline(struct Client *, struct Client *, int, const char **);
@ -213,8 +214,6 @@ apply_dline(struct Client *source_p, const char *dlhost, int tdline_time, char *
{
struct ConfItem *aconf;
char *oper_reason;
char dlbuffer[IRCD_BUFSIZE];
const char *current_date;
struct rb_sockaddr_storage daddr;
int t = AF_INET, ty, b;
const char *creason;
@ -285,11 +284,13 @@ apply_dline(struct Client *source_p, const char *dlhost, int tdline_time, char *
}
rb_set_time();
current_date = smalldate();
aconf = make_conf();
aconf->status = CONF_DLINE;
aconf->created = rb_current_time();
aconf->host = rb_strdup(dlhost);
aconf->passwd = rb_strdup(reason);
aconf->info.oper = operhash_add(get_oper_name(source_p));
/* Look for an oper reason */
if((oper_reason = strchr(reason, '|')) != NULL)
@ -303,10 +304,6 @@ apply_dline(struct Client *source_p, const char *dlhost, int tdline_time, char *
if(tdline_time > 0)
{
rb_snprintf(dlbuffer, sizeof(dlbuffer),
"Temporary D-line %d min. - %s (%s)",
(int) (tdline_time / 60), reason, current_date);
aconf->passwd = rb_strdup(dlbuffer);
aconf->hold = rb_current_time() + tdline_time;
add_temp_dline(aconf);
@ -335,8 +332,6 @@ apply_dline(struct Client *source_p, const char *dlhost, int tdline_time, char *
}
else
{
rb_snprintf(dlbuffer, sizeof(dlbuffer), "%s (%s)", reason, current_date);
aconf->passwd = rb_strdup(dlbuffer);
add_conf_by_address(aconf->host, CONF_DLINE, NULL, NULL, aconf);
bandb_add(BANDB_DLINE, source_p, aconf->host, NULL,

View File

@ -530,6 +530,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

@ -44,6 +44,7 @@
#include "modules.h"
#include "reject.h"
#include "bandbi.h"
#include "operhash.h"
static int mo_kline(struct Client *, struct Client *, int, const char **);
static int ms_kline(struct Client *, struct Client *, int, const char **);
@ -70,19 +71,21 @@ DECLARE_MODULE_AV1(kline, NULL, NULL, kline_clist, NULL, NULL, "$Revision$");
static int find_user_host(struct Client *source_p, const char *userhost, char *user, char *host);
static int valid_comment(struct Client *source_p, char *comment);
static int valid_user_host(struct Client *source_p, const char *user, const char *host);
static int valid_wild_card(struct Client *source_p, const char *user, const char *host);
static void handle_remote_kline(struct Client *source_p, int tkline_time,
const char *user, const char *host, const char *reason);
static void apply_kline(struct Client *source_p, struct ConfItem *aconf,
const char *reason, const char *oper_reason, const char *current_date);
const char *reason, const char *oper_reason);
static void apply_tkline(struct Client *source_p, struct ConfItem *aconf,
const char *, const char *, const char *, int);
const char *, const char *, int);
static void apply_prop_kline(struct Client *source_p, struct ConfItem *aconf,
const char *, const char *, int);
static int already_placed_kline(struct Client *, const char *, const char *, int);
static void handle_remote_unkline(struct Client *source_p, const char *user, const char *host);
static void remove_permkline_match(struct Client *, struct ConfItem *);
static int remove_temp_kline(struct Client *, struct ConfItem *);
static void remove_prop_kline(struct Client *, struct ConfItem *);
/* mo_kline()
*
@ -98,14 +101,13 @@ mo_kline(struct Client *client_p, struct Client *source_p, int parc, const char
char def[] = "No Reason";
char user[USERLEN + 2];
char host[HOSTLEN + 2];
char buffer[IRCD_BUFSIZE];
char *reason = def;
char *oper_reason;
const char *current_date;
const char *target_server = NULL;
struct ConfItem *aconf;
int tkline_time = 0;
int loc = 1;
int propagated = ConfigFileEntry.use_propagated_bans;
if(!IsOperK(source_p))
{
@ -154,27 +156,46 @@ mo_kline(struct Client *client_p, struct Client *source_p, int parc, const char
/* If we are sending it somewhere that doesnt include us, stop */
if(!match(target_server, me.name))
return 0;
/* Set as local-only. */
propagated = 0;
}
/* if we have cluster servers, send it to them.. */
else if(rb_dlink_list_length(&cluster_conf_list) > 0)
else if(!propagated && rb_dlink_list_length(&cluster_conf_list) > 0)
cluster_generic(source_p, "KLINE",
(tkline_time > 0) ? SHARED_TKLINE : SHARED_PKLINE, CAP_KLN,
"%lu %s %s :%s", tkline_time, user, host, reason);
if(!valid_user_host(source_p, user, host) ||
!valid_wild_card(source_p, user, host) || !valid_comment(source_p, reason))
!valid_comment(source_p, reason))
return 0;
if(!valid_wild_card(user, host))
{
sendto_one_notice(source_p,
":Please include at least %d non-wildcard "
"characters with the user@host",
ConfigFileEntry.min_nonwildcard);
return 0;
}
if(propagated && tkline_time == 0)
{
sendto_one_notice(source_p, ":Cannot set a permanent global ban");
return 0;
}
if(already_placed_kline(source_p, user, host, tkline_time))
return 0;
rb_set_time();
current_date = smalldate();
aconf = make_conf();
aconf->status = CONF_KILL;
aconf->created = rb_current_time();
aconf->host = rb_strdup(host);
aconf->user = rb_strdup(user);
aconf->port = 0;
aconf->info.oper = operhash_add(get_oper_name(source_p));
/* Look for an oper reason */
if((oper_reason = strchr(reason, '|')) != NULL)
@ -185,21 +206,14 @@ mo_kline(struct Client *client_p, struct Client *source_p, int parc, const char
if(!EmptyString(oper_reason))
aconf->spasswd = rb_strdup(oper_reason);
}
aconf->passwd = rb_strdup(reason);
if(tkline_time > 0)
{
rb_snprintf(buffer, sizeof(buffer),
"Temporary K-line %d min. - %s (%s)",
(int) (tkline_time / 60), reason, current_date);
aconf->passwd = rb_strdup(buffer);
apply_tkline(source_p, aconf, reason, oper_reason, current_date, tkline_time);
}
if(propagated)
apply_prop_kline(source_p, aconf, reason, oper_reason, tkline_time);
else if(tkline_time > 0)
apply_tkline(source_p, aconf, reason, oper_reason, tkline_time);
else
{
rb_snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
aconf->passwd = rb_strdup(buffer);
apply_kline(source_p, aconf, reason, oper_reason, current_date);
}
apply_kline(source_p, aconf, reason, oper_reason);
if(ConfigFileEntry.kline_delay)
{
@ -264,8 +278,6 @@ static void
handle_remote_kline(struct Client *source_p, int tkline_time,
const char *user, const char *host, const char *kreason)
{
char buffer[BUFSIZE];
const char *current_date;
char *reason = LOCAL_COPY(kreason);
struct ConfItem *aconf = NULL;
char *oper_reason;
@ -276,17 +288,28 @@ handle_remote_kline(struct Client *source_p, int tkline_time,
return;
if(!valid_user_host(source_p, user, host) ||
!valid_wild_card(source_p, user, host) || !valid_comment(source_p, reason))
!valid_comment(source_p, reason))
return;
if(!valid_wild_card(user, host))
{
sendto_one_notice(source_p,
":Please include at least %d non-wildcard "
"characters with the user@host",
ConfigFileEntry.min_nonwildcard);
return;
}
if(already_placed_kline(source_p, user, host, tkline_time))
return;
aconf = make_conf();
aconf->status = CONF_KILL;
aconf->created = rb_current_time();
aconf->user = rb_strdup(user);
aconf->host = rb_strdup(host);
aconf->info.oper = operhash_add(get_oper_name(source_p));
/* Look for an oper reason */
if((oper_reason = strchr(reason, '|')) != NULL)
@ -297,23 +320,12 @@ handle_remote_kline(struct Client *source_p, int tkline_time,
if(!EmptyString(oper_reason))
aconf->spasswd = rb_strdup(oper_reason);
}
current_date = smalldate();
aconf->passwd = rb_strdup(reason);
if(tkline_time > 0)
{
rb_snprintf(buffer, sizeof(buffer),
"Temporary K-line %d min. - %s (%s)",
(int) (tkline_time / 60), reason, current_date);
aconf->passwd = rb_strdup(buffer);
apply_tkline(source_p, aconf, reason, oper_reason, current_date, tkline_time);
}
apply_tkline(source_p, aconf, reason, oper_reason, tkline_time);
else
{
rb_snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
aconf->passwd = rb_strdup(buffer);
apply_kline(source_p, aconf, reason, oper_reason, current_date);
}
apply_kline(source_p, aconf, reason, oper_reason);
if(ConfigFileEntry.kline_delay)
{
@ -344,6 +356,7 @@ mo_unkline(struct Client *client_p, struct Client *source_p, int parc, const cha
char splat[] = "*";
char *h = LOCAL_COPY(parv[1]);
struct ConfItem *aconf;
int propagated = 1;
if(!IsOperUnkline(source_p))
{
@ -395,17 +408,32 @@ mo_unkline(struct Client *client_p, struct Client *source_p, int parc, const cha
if(match(parv[3], me.name) == 0)
return 0;
propagated = 0;
}
else if(rb_dlink_list_length(&cluster_conf_list) > 0)
aconf = find_exact_conf_by_address(host, CONF_KILL, user);
/* No clustering for removing a propagated kline */
if(propagated && (aconf == NULL || !aconf->lifetime) &&
rb_dlink_list_length(&cluster_conf_list) > 0)
cluster_generic(source_p, "UNKLINE", SHARED_UNKLINE, CAP_UNKLN,
"%s %s", user, host);
aconf = find_exact_conf_by_address(host, CONF_KILL, user);
if(aconf == NULL)
{
sendto_one_notice(source_p, ":No K-Line for %s@%s", user, host);
return 0;
}
if(aconf->lifetime)
{
if(propagated)
remove_prop_kline(source_p, aconf);
else
sendto_one_notice(source_p, ":Cannot remove global K-Line %s@%s on specific servers", user, host);
return 0;
}
if(remove_temp_kline(source_p, aconf))
return 0;
@ -464,6 +492,11 @@ handle_remote_unkline(struct Client *source_p, const char *user, const char *hos
sendto_one_notice(source_p, ":No K-Line for %s@%s", user, host);
return;
}
if(aconf->lifetime)
{
sendto_one_notice(source_p, ":Cannot remove global K-Line %s@%s on specific servers", user, host);
return;
}
if(remove_temp_kline(source_p, aconf))
return;
@ -480,7 +513,7 @@ handle_remote_unkline(struct Client *source_p, const char *user, const char *hos
*/
static void
apply_kline(struct Client *source_p, struct ConfItem *aconf,
const char *reason, const char *oper_reason, const char *current_date)
const char *reason, const char *oper_reason)
{
add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
bandb_add(BANDB_KLINE, source_p, aconf->user, aconf->host,
@ -517,7 +550,7 @@ apply_kline(struct Client *source_p, struct ConfItem *aconf,
*/
static void
apply_tkline(struct Client *source_p, struct ConfItem *aconf,
const char *reason, const char *oper_reason, const char *current_date, int tkline_time)
const char *reason, const char *oper_reason, int tkline_time)
{
aconf->hold = rb_current_time() + tkline_time;
add_temp_kline(aconf);
@ -547,6 +580,54 @@ apply_tkline(struct Client *source_p, struct ConfItem *aconf,
tkline_time / 60, aconf->user, aconf->host);
}
static void
apply_prop_kline(struct Client *source_p, struct ConfItem *aconf,
const char *reason, const char *oper_reason, int tkline_time)
{
aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY;
aconf->hold = rb_current_time() + tkline_time;
aconf->lifetime = aconf->hold;
replace_old_ban(aconf);
rb_dlinkAddAlloc(aconf, &prop_bans);
add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
/* no oper reason.. */
if(EmptyString(oper_reason))
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s added global %d min. K-Line for [%s@%s] [%s]",
get_oper_name(source_p), tkline_time / 60,
aconf->user, aconf->host, reason);
ilog(L_KLINE, "K %s %d %s %s %s",
get_oper_name(source_p), tkline_time / 60, aconf->user, aconf->host, reason);
}
else
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s added global %d min. K-Line for [%s@%s] [%s|%s]",
get_oper_name(source_p), tkline_time / 60,
aconf->user, aconf->host, reason, oper_reason);
ilog(L_KLINE, "K %s %d %s %s %s|%s",
get_oper_name(source_p), tkline_time / 60,
aconf->user, aconf->host, reason, oper_reason);
}
sendto_one_notice(source_p, ":Added global %d min. K-Line [%s@%s]",
tkline_time / 60, aconf->user, aconf->host);
sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
":%s BAN K %s %s %lu %d %d * :%s%s%s",
source_p->id, aconf->user, aconf->host,
(unsigned long)aconf->created,
(int)(aconf->hold - aconf->created),
(int)(aconf->lifetime - aconf->created),
reason,
oper_reason ? "|" : "",
oper_reason ? oper_reason : "");
}
/* find_user_host()
*
* inputs - client placing kline, user@host, user buffer, host buffer
@ -610,65 +691,6 @@ valid_user_host(struct Client *source_p, const char *luser, const char *lhost)
return 1;
}
/* valid_wild_card()
*
* input - user buffer, host buffer
* output - 0 if invalid, 1 if valid
* side effects -
*/
static int
valid_wild_card(struct Client *source_p, const char *luser, const char *lhost)
{
const char *p;
char tmpch;
int nonwild = 0;
int bitlen;
/* user has no wildcards, always accept -- jilles */
if(!strchr(luser, '?') && !strchr(luser, '*'))
return 1;
/* check there are enough non wildcard chars */
p = luser;
while((tmpch = *p++))
{
if(!IsKWildChar(tmpch))
{
/* found enough chars, return */
if(++nonwild >= ConfigFileEntry.min_nonwildcard)
return 1;
}
}
/* try host, as user didnt contain enough */
/* special case for cidr masks -- jilles */
if((p = strrchr(lhost, '/')) != NULL && IsDigit(p[1]))
{
bitlen = atoi(p + 1);
/* much like non-cidr for ipv6, rather arbitrary for ipv4 */
if(bitlen > 0
&& bitlen >=
(strchr(lhost, ':') ? 4 * (ConfigFileEntry.min_nonwildcard - nonwild) : 6 -
2 * nonwild))
return 1;
}
else
{
p = lhost;
while((tmpch = *p++))
{
if(!IsKWildChar(tmpch))
if(++nonwild >= ConfigFileEntry.min_nonwildcard)
return 1;
}
}
sendto_one_notice(source_p,
":Please include at least %d non-wildcard "
"characters with the user@host", ConfigFileEntry.min_nonwildcard);
return 0;
}
/*
* valid_comment
* inputs - pointer to client
@ -819,3 +841,39 @@ remove_temp_kline(struct Client *source_p, struct ConfItem *aconf)
return NO;
}
static void
remove_prop_kline(struct Client *source_p, struct ConfItem *aconf)
{
rb_dlink_node *ptr;
ptr = rb_dlinkFind(aconf, &prop_bans);
if (!ptr)
return;
sendto_one_notice(source_p,
":Un-klined [%s@%s] from global k-lines",
aconf->user, aconf->host);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s has removed the global K-Line for: [%s@%s]",
get_oper_name(source_p), aconf->user,
aconf->host);
ilog(L_KLINE, "UK %s %s %s",
get_oper_name(source_p), aconf->user, aconf->host);
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 K %s %s %lu %d %d * :*",
source_p->id, aconf->user, aconf->host,
(unsigned long)aconf->created,
0,
(int)(aconf->lifetime - aconf->created));
remove_reject_mask(aconf->user, aconf->host);
deactivate_conf(aconf, ptr);
}

View File

@ -174,7 +174,7 @@ rehash_txlines(struct Client *source_p)
{
aconf = ptr->data;
if(!aconf->hold)
if(!aconf->hold || aconf->lifetime)
continue;
free_conf(aconf);
@ -199,7 +199,7 @@ rehash_tresvs(struct Client *source_p)
{
aconf = ptr->data;
if(!aconf->hold)
if(!aconf->hold || aconf->lifetime)
continue;
free_conf(aconf);
@ -211,7 +211,7 @@ rehash_tresvs(struct Client *source_p)
{
aconf = ptr->data;
if(!aconf->hold)
if(!aconf->hold || aconf->lifetime)
continue;
free_conf(aconf);

View File

@ -38,6 +38,7 @@
#include "hash.h"
#include "logger.h"
#include "bandbi.h"
#include "operhash.h"
static int mo_resv(struct Client *, struct Client *, int, const char **);
static int ms_resv(struct Client *, struct Client *, int, const char **);
@ -61,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()
@ -85,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))
{
@ -114,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]))
@ -132,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;
}
@ -160,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;
}
@ -171,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;
}
@ -184,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;
@ -218,12 +228,36 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
aconf = make_conf();
aconf->status = CONF_RESV_CHANNEL;
aconf->port = 0;
aconf->created = rb_current_time();
aconf->host = rb_strdup(name);
aconf->passwd = rb_strdup(reason);
add_to_resv_hash(aconf->host, aconf);
resv_chan_forcepart(aconf->host, aconf->passwd, temp_time);
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. 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;
@ -247,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))
{
@ -281,11 +318,36 @@ parse_resv(struct Client *source_p, const char *name, const char *reason, int te
aconf = make_conf();
aconf->status = CONF_RESV_NICK;
aconf->port = 0;
aconf->created = rb_current_time();
aconf->host = rb_strdup(name);
aconf->passwd = rb_strdup(reason);
rb_dlinkAddAlloc(aconf, &resv_conf_list);
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. 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;
@ -309,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);
@ -375,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");
@ -394,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;
}
@ -443,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)
@ -480,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;
@ -494,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);
@ -515,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

@ -94,6 +94,7 @@ static void stats_tdeny(struct Client *);
static void stats_deny(struct Client *);
static void stats_exempt(struct Client *);
static void stats_events(struct Client *);
static void stats_prop_klines(struct Client *);
static void stats_hubleaf(struct Client *);
static void stats_auth(struct Client *);
static void stats_tklines(struct Client *);
@ -137,6 +138,7 @@ static struct StatsStruct stats_cmd_table[] = {
{'E', stats_events, 1, 1, },
{'f', stats_comm, 1, 1, },
{'F', stats_comm, 1, 1, },
{'g', stats_prop_klines, 1, 0, },
{'h', stats_hubleaf, 0, 0, },
{'H', stats_hubleaf, 0, 0, },
{'i', stats_auth, 0, 0, },
@ -450,6 +452,32 @@ stats_events (struct Client *source_p)
rb_dump_events(stats_events_cb, source_p);
}
static void
stats_prop_klines(struct Client *source_p)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
char *user, *host, *pass, *oper_reason;
RB_DLINK_FOREACH(ptr, prop_bans.head)
{
aconf = ptr->data;
/* Skip non-klines and deactivated klines. */
if(aconf->status != CONF_KILL)
continue;
get_printable_kline(source_p, aconf, &host, &pass,
&user, &oper_reason);
sendto_one_numeric(source_p, RPL_STATSKLINE,
form_str(RPL_STATSKLINE),
'g', host, user, pass,
oper_reason ? "|" : "",
oper_reason ? oper_reason : "");
}
}
static void
stats_hubleaf(struct Client *source_p)
{

View File

@ -218,7 +218,7 @@ mo_testline(struct Client *client_p, struct Client *source_p, int parc, const ch
if(aconf && aconf->status & CONF_CLIENT)
{
sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
aconf->name, EmptyString(aconf->spasswd) ? "<NULL>" : aconf->spasswd,
aconf->info.name, EmptyString(aconf->spasswd) ? "<NULL>" : aconf->spasswd,
show_iline_prefix(source_p, aconf, aconf->user),
aconf->host, aconf->port, aconf->className);
return 0;

View File

@ -51,6 +51,7 @@
#include "s_newconf.h"
#include "reject.h"
#include "bandbi.h"
#include "operhash.h"
static int mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static int ms_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
@ -78,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,
@ -88,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()
@ -106,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))
{
@ -151,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)
@ -165,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;
}
@ -225,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()
@ -269,17 +281,45 @@ 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;
aconf = make_conf();
aconf->status = CONF_XLINE;
aconf->created = rb_current_time();
aconf->host = rb_strdup(name);
aconf->passwd = rb_strdup(reason);
collapse(aconf->host);
if(temp_time > 0)
aconf->info.oper = operhash_add(get_oper_name(source_p));
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;
@ -362,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");
@ -381,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;
}
@ -430,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;
@ -447,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);
@ -473,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

@ -76,6 +76,7 @@ SRCS = \
monitor.c \
newconf.c \
numeric.c \
operhash.c \
packet.c \
parse.c \
privilege.c \

View File

@ -46,6 +46,7 @@
#include "send.h"
#include "ircd.h"
#include "msg.h" /* XXX: MAXPARA */
#include "operhash.h"
static char bandb_add_letter[LAST_BANDB_TYPE] = {
'K', 'D', 'X', 'R'
@ -170,8 +171,7 @@ bandb_handle_ban(char *parv[], int parc)
aconf->user = rb_strdup(parv[para++]);
aconf->host = rb_strdup(parv[para++]);
/* We do not have the 'oper' field yet. */
para++;
aconf->info.oper = operhash_add(parv[para++]);
switch (parv[0][0])
{

View File

@ -1532,6 +1532,57 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
}
}
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);
}
}
}
/* Check what we will forward to, without sending any notices to the user
* -- jilles
*/

View File

@ -775,8 +775,8 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
case CHFL_QUIET:
list = &chptr->quietlist;
errorval = SM_ERR_RPL_Q;
rpl_list = RPL_BANLIST;
rpl_endlist = RPL_ENDOFBANLIST;
rpl_list = RPL_QUIETLIST;
rpl_endlist = RPL_ENDOFQUIETLIST;
mems = ALL_MEMBERS;
caps = 0;
break;
@ -824,10 +824,7 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
me.name, source_p->name, chptr->chname,
banptr->banstr, banptr->who, banptr->when);
}
if (mode_type == CHFL_QUIET)
sendto_one(source_p, ":%s %d %s %s :End of Channel Quiet List", me.name, rpl_endlist, source_p->name, chptr->chname);
else
sendto_one(source_p, form_str(rpl_endlist), me.name, source_p->name, chptr->chname);
sendto_one(source_p, form_str(rpl_endlist), me.name, source_p->name, chptr->chname);
return;
}

View File

@ -424,10 +424,10 @@ notify_banned_client(struct Client *client_p, struct ConfItem *aconf, int ban)
const char *reason = NULL;
const char *exit_reason = conn_closed;
if(ConfigFileEntry.kline_with_reason && !EmptyString(aconf->passwd))
if(ConfigFileEntry.kline_with_reason)
{
reason = aconf->passwd;
exit_reason = aconf->passwd;
reason = get_user_ban_reason(aconf);
exit_reason = reason;
}
else
{

View File

@ -390,7 +390,7 @@ find_address_conf(const char *host, const char *sockhost, const char *user,
/* if theres a spoof, check it against klines.. */
if(IsConfDoSpoofIp(iconf))
{
char *p = strchr(iconf->name, '@');
char *p = strchr(iconf->info.name, '@');
/* note, we dont need to pass sockhost here, as its
* guaranteed to not match by whats above.. --anfl
@ -398,11 +398,11 @@ find_address_conf(const char *host, const char *sockhost, const char *user,
if(p)
{
*p = '\0';
kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->name, NULL);
kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->info.name, NULL);
*p = '@';
}
else
kconf = find_conf_by_address(iconf->name, NULL, NULL, ip, CONF_KILL, aftype, vuser, NULL);
kconf = find_conf_by_address(iconf->info.name, NULL, NULL, ip, CONF_KILL, aftype, vuser, NULL);
if(kconf)
return kconf;

View File

@ -480,6 +480,7 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
char buf[BUFSIZE];
struct ConfItem *aconf;
static time_t last_oper_notice = 0;
int len;
if(listener->ssl && (!ssl_ok || !get_ssld_count()))
{
@ -519,7 +520,8 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
if(ConfigFileEntry.dline_with_reason)
{
if (rb_snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", aconf->passwd) >= (int)(sizeof(buf)-1))
len = rb_snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", get_user_ban_reason(aconf));
if (len >= (int)(sizeof(buf)-1))
{
buf[sizeof(buf) - 3] = '\r';
buf[sizeof(buf) - 2] = '\n';

View File

@ -180,7 +180,8 @@ ilog(ilogfile dest, const char *format, ...)
rb_vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
rb_snprintf(buf2, sizeof(buf2), "%s %s\n", smalldate(), buf);
rb_snprintf(buf2, sizeof(buf2), "%s %s\n",
smalldate(rb_current_time()), buf);
if(fputs(buf2, logfile) < 0)
{
@ -266,11 +267,10 @@ report_operspy(struct Client *source_p, const char *token, const char *arg)
}
const char *
smalldate(void)
smalldate(time_t ltime)
{
static char buf[MAX_DATE_STRING];
struct tm *lt;
time_t ltime = rb_current_time();
lt = localtime(&ltime);

View File

@ -749,8 +749,8 @@ static const char * replies[] = {
/* 725 RPL_TESTLINE */ ":%s 725 %s %c %ld %s :%s",
/* 726 RPL_NOTESTLINE */ ":%s 726 %s %s :No matches",
/* 727 RPL_TESTMASKGECOS */ ":%s 727 %s %d %d %s!%s@%s %s :Local/remote clients match",
/* 728 */ NULL,
/* 729 */ NULL,
/* 728 RPL_QUIETLIST */ ":%s 728 %s %s q %s %s %lu",
/* 729 RPL_ENDOFQUIETLIST */ ":%s 729 %s %s q :End of Channel Quiet List",
/* 730 RPL_MONONLINE */ ":%s 730 %s :%s",
/* 731 RPL_MONOFFLINE */ ":%s 731 %s :%s",
/* 732 RPL_MONLIST */ ":%s 732 %s :%s",
@ -761,8 +761,8 @@ static const char * replies[] = {
/* 737 ERR_NOCOMMONCHAN*/ "%s :is in +G mode (server-side ignore) and you do not share a common channel with them.",
/* 738 */ NULL,
/* 739 */ NULL,
/* 740 */ ":%s 740 %s :%s",
/* 741 */ ":%s 741 %s :End of CHALLENGE",
/* 740 RPL_RSACHALLENGE2*/ ":%s 740 %s :%s",
/* 741 RPL_ENDOFRSACHALLENGE2*/ ":%s 741 %s :End of CHALLENGE",
/* 742 */ NULL,
/* 743 */ NULL,
/* 744 */ NULL,

View File

@ -58,6 +58,7 @@
struct module **modlist = NULL;
static const char *core_module_table[] = {
"m_ban",
"m_die",
"m_error",
"m_join",
@ -880,7 +881,7 @@ unload_one_module(const char *name, int warn)
dlclose(modlist[modindex]->address);
rb_free(modlist[modindex]->name);
memcpy(&modlist[modindex], &modlist[modindex + 1],
memmove(&modlist[modindex], &modlist[modindex + 1],
sizeof(struct module) * ((num_mods - 1) - modindex));
if(num_mods != 0)

View File

@ -952,8 +952,8 @@ conf_end_auth(struct TopConf *tc)
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
if(EmptyString(yy_aconf->name))
yy_aconf->name = rb_strdup("NOMATCH");
if(EmptyString(yy_aconf->info.name))
yy_aconf->info.name = rb_strdup("NOMATCH");
/* didnt even get one ->host? */
if(EmptyString(yy_aconf->host))
@ -987,7 +987,7 @@ conf_end_auth(struct TopConf *tc)
yy_tmp->spasswd = rb_strdup(yy_aconf->spasswd);
/* this will always exist.. */
yy_tmp->name = rb_strdup(yy_aconf->name);
yy_tmp->info.name = rb_strdup(yy_aconf->info.name);
if(yy_aconf->className)
yy_tmp->className = rb_strdup(yy_aconf->className);
@ -1138,8 +1138,8 @@ conf_set_auth_spoof(void *data)
return;
}
rb_free(yy_aconf->name);
yy_aconf->name = rb_strdup(data);
rb_free(yy_aconf->info.name);
yy_aconf->info.name = rb_strdup(data);
yy_aconf->flags |= CONF_FLAGS_SPOOF_IP;
}
@ -1155,8 +1155,8 @@ static void
conf_set_auth_redir_serv(void *data)
{
yy_aconf->flags |= CONF_FLAGS_REDIR;
rb_free(yy_aconf->name);
yy_aconf->name = rb_strdup(data);
rb_free(yy_aconf->info.name);
yy_aconf->info.name = rb_strdup(data);
}
static void
@ -2253,6 +2253,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 },
{ "expire_override_time", CF_TIME, NULL, 0, &ConfigFileEntry.expire_override_time},
{ "\0", 0, NULL, 0, NULL }
};

136
src/operhash.c Normal file
View File

@ -0,0 +1,136 @@
/* ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
* operhash.c - Hashes nick!user@host{oper}
*
* Copyright (C) 2005 Lee Hardy <lee -at- leeh.co.uk>
* Copyright (C) 2005 ircd-ratbox development team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id: operhash.c 26094 2008-09-19 15:33:46Z androsyn $
*/
#include <ratbox_lib.h>
#include "stdinc.h"
#include "match.h"
#include "hash.h"
#include "operhash.h"
#define OPERHASH_MAX_BITS 7
#define OPERHASH_MAX (1<<OPERHASH_MAX_BITS)
#define hash_opername(x) fnv_hash_upper((const unsigned char *)(x), OPERHASH_MAX_BITS)
struct operhash_entry
{
char *name;
int refcount;
};
static rb_dlink_list operhash_table[OPERHASH_MAX];
const char *
operhash_add(const char *name)
{
struct operhash_entry *ohash;
unsigned int hashv;
rb_dlink_node *ptr;
if(EmptyString(name))
return NULL;
hashv = hash_opername(name);
RB_DLINK_FOREACH(ptr, operhash_table[hashv].head)
{
ohash = ptr->data;
if(!irccmp(ohash->name, name))
{
ohash->refcount++;
return ohash->name;
}
}
ohash = rb_malloc(sizeof(struct operhash_entry));
ohash->refcount = 1;
ohash->name = rb_strdup(name);
rb_dlinkAddAlloc(ohash, &operhash_table[hashv]);
return ohash->name;
}
const char *
operhash_find(const char *name)
{
struct operhash_entry *ohash;
unsigned int hashv;
rb_dlink_node *ptr;
if(EmptyString(name))
return NULL;
hashv = hash_opername(name);
RB_DLINK_FOREACH(ptr, operhash_table[hashv].head)
{
ohash = ptr->data;
if(!irccmp(ohash->name, name))
return ohash->name;
}
return NULL;
}
void
operhash_delete(const char *name)
{
struct operhash_entry *ohash;
unsigned int hashv;
rb_dlink_node *ptr;
if(EmptyString(name))
return;
hashv = hash_opername(name);
RB_DLINK_FOREACH(ptr, operhash_table[hashv].head)
{
ohash = ptr->data;
if(irccmp(ohash->name, name))
continue;
ohash->refcount--;
if(ohash->refcount == 0)
{
rb_free(ohash->name);
rb_free(ohash);
rb_dlinkDestroy(ptr, &operhash_table[hashv]);
return;
}
}
}

View File

@ -51,6 +51,7 @@
#include "privilege.h"
#include "sslproc.h"
#include "bandbi.h"
#include "operhash.h"
struct config_server_hide ConfigServerHide;
@ -63,6 +64,8 @@ extern char linebuf[];
static rb_bh *confitem_heap = NULL;
rb_dlink_list prop_bans;
rb_dlink_list temp_klines[LAST_TEMP_TYPE];
rb_dlink_list temp_dlines[LAST_TEMP_TYPE];
rb_dlink_list service_list;
@ -73,6 +76,7 @@ static void validate_conf(void);
static void read_conf(FILE *);
static void clear_out_old_conf(void);
static void expire_prop_bans(void *list);
static void expire_temp_kd(void *list);
static void reorganise_temp_kd(void *list);
@ -87,6 +91,8 @@ init_s_conf(void)
{
confitem_heap = rb_bh_create(sizeof(struct ConfItem), CONFITEM_HEAP_SIZE, "confitem_heap");
rb_event_addish("expire_prop_bans", expire_prop_bans, &prop_bans, 60);
rb_event_addish("expire_temp_klines", expire_temp_kd, &temp_klines[TEMP_MIN], 60);
rb_event_addish("expire_temp_dlines", expire_temp_kd, &temp_dlines[TEMP_MIN], 60);
@ -143,11 +149,15 @@ free_conf(struct ConfItem *aconf)
rb_free(aconf->passwd);
rb_free(aconf->spasswd);
rb_free(aconf->name);
rb_free(aconf->className);
rb_free(aconf->user);
rb_free(aconf->host);
if(IsConfBan(aconf))
operhash_delete(aconf->info.oper);
else
rb_free(aconf->info.name);
rb_bh_free(confitem_heap, aconf);
}
@ -334,7 +344,7 @@ verify_access(struct Client *client_p, const char *username)
if(aconf->flags & CONF_FLAGS_REDIR)
{
sendto_one_numeric(client_p, RPL_REDIR, form_str(RPL_REDIR),
aconf->name ? aconf->name : "", aconf->port);
aconf->info.name ? aconf->info.name : "", aconf->port);
return (NOT_AUTHORISED);
}
@ -351,35 +361,34 @@ verify_access(struct Client *client_p, const char *username)
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s spoofing: %s as %s",
client_p->name,
show_ip(NULL, client_p) ? client_p->host : aconf->name,
aconf->name);
show_ip(NULL, client_p) ? client_p->host : aconf->info.name,
aconf->info.name);
}
/* user@host spoof */
if((p = strchr(aconf->name, '@')) != NULL)
if((p = strchr(aconf->info.name, '@')) != NULL)
{
char *host = p+1;
*p = '\0';
rb_strlcpy(client_p->username, aconf->name,
rb_strlcpy(client_p->username, aconf->info.name,
sizeof(client_p->username));
rb_strlcpy(client_p->host, host,
sizeof(client_p->host));
*p = '@';
}
else
rb_strlcpy(client_p->host, aconf->name, sizeof(client_p->host));
rb_strlcpy(client_p->host, aconf->info.name, sizeof(client_p->host));
}
return (attach_iline(client_p, aconf));
}
else if(aconf->status & CONF_KILL)
{
if(ConfigFileEntry.kline_with_reason)
{
sendto_one(client_p,
form_str(ERR_YOUREBANNEDCREEP),
me.name, client_p->name, aconf->passwd);
}
me.name, client_p->name,
get_user_ban_reason(aconf));
add_reject(client_p, aconf->user, aconf->host);
return (BANNED_CLIENT);
}
@ -740,6 +749,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;
ConfigFileEntry.secret_channels_in_whois = NO;
#ifdef HAVE_LIBZ
@ -998,6 +1008,192 @@ add_temp_dline(struct ConfItem *aconf)
add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, NULL, aconf);
}
/* valid_wild_card()
*
* input - user buffer, host buffer
* output - 0 if invalid, 1 if valid
* side effects -
*/
int
valid_wild_card(const char *luser, const char *lhost)
{
const char *p;
char tmpch;
int nonwild = 0;
int bitlen;
/* user has no wildcards, always accept -- jilles */
if(!strchr(luser, '?') && !strchr(luser, '*'))
return 1;
/* check there are enough non wildcard chars */
p = luser;
while((tmpch = *p++))
{
if(!IsKWildChar(tmpch))
{
/* found enough chars, return */
if(++nonwild >= ConfigFileEntry.min_nonwildcard)
return 1;
}
}
/* try host, as user didnt contain enough */
/* special case for cidr masks -- jilles */
if((p = strrchr(lhost, '/')) != NULL && IsDigit(p[1]))
{
bitlen = atoi(p + 1);
/* much like non-cidr for ipv6, rather arbitrary for ipv4 */
if(bitlen > 0
&& bitlen >=
(strchr(lhost, ':') ? 4 * (ConfigFileEntry.min_nonwildcard - nonwild) : 6 -
2 * nonwild))
return 1;
}
else
{
p = lhost;
while((tmpch = *p++))
{
if(!IsKWildChar(tmpch))
if(++nonwild >= ConfigFileEntry.min_nonwildcard)
return 1;
}
}
return 0;
}
rb_dlink_node *
find_prop_ban(unsigned int status, const char *user, const char *host)
{
rb_dlink_node *ptr;
struct ConfItem *aconf;
RB_DLINK_FOREACH(ptr, prop_bans.head)
{
aconf = ptr->data;
if((aconf->status & ~CONF_ILLEGAL) == status &&
(!user || !aconf->user ||
!irccmp(aconf->user, user)) &&
!irccmp(aconf->host, host))
return ptr;
}
return NULL;
}
void
deactivate_conf(struct ConfItem *aconf, rb_dlink_node *ptr)
{
int i;
s_assert(ptr->data == aconf);
switch (aconf->status)
{
case CONF_KILL:
if (aconf->lifetime == 0 &&
aconf->flags & CONF_FLAGS_TEMPORARY)
for (i = 0; i < LAST_TEMP_TYPE; i++)
rb_dlinkFindDestroy(aconf, &temp_klines[i]);
/* Make sure delete_one_address_conf() does not
* free the aconf.
*/
aconf->clients++;
delete_one_address_conf(aconf->host, aconf);
aconf->clients--;
break;
case CONF_DLINE:
if (aconf->lifetime == 0 &&
aconf->flags & CONF_FLAGS_TEMPORARY)
for (i = 0; i < LAST_TEMP_TYPE; i++)
rb_dlinkFindDestroy(aconf, &temp_dlines[i]);
aconf->clients++;
delete_one_address_conf(aconf->host, aconf);
aconf->clients--;
break;
case CONF_XLINE:
rb_dlinkFindDestroy(aconf, &xline_conf_list);
break;
case CONF_RESV_NICK:
rb_dlinkFindDestroy(aconf, &resv_conf_list);
break;
case CONF_RESV_CHANNEL:
del_from_resv_hash(aconf->host, aconf);
break;
}
if (aconf->lifetime != 0 && rb_current_time() < aconf->lifetime)
aconf->status |= CONF_ILLEGAL;
else
{
if (aconf->lifetime != 0)
rb_dlinkDestroy(ptr, &prop_bans);
free_conf(aconf);
}
}
/* 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)
{
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
struct ConfItem *aconf;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, ((rb_dlink_list *) list)->head)
{
aconf = ptr->data;
if(aconf->lifetime <= rb_current_time() ||
(aconf->hold <= rb_current_time() &&
!(aconf->status & CONF_ILLEGAL)))
{
/* Alert opers that a TKline expired - Hwy */
/* XXX show what type of ban it is */
if(ConfigFileEntry.tkline_expire_notices &&
!(aconf->status & CONF_ILLEGAL))
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Propagated ban for [%s%s%s] expired",
aconf->user ? aconf->user : "",
aconf->user ? "@" : "",
aconf->host ? aconf->host : "*");
/* will destroy or mark illegal */
deactivate_conf(aconf, ptr);
}
}
}
/* expire_tkline()
*
* inputs - list pointer
@ -1116,7 +1312,7 @@ get_printable_conf(struct ConfItem *aconf, char **name, char **host,
static char null[] = "<NULL>";
static char zero[] = "default";
*name = EmptyString(aconf->name) ? null : aconf->name;
*name = EmptyString(aconf->info.name) ? null : aconf->info.name;
*host = EmptyString(aconf->host) ? null : aconf->host;
*pass = EmptyString(aconf->passwd) ? null : aconf->passwd;
*user = EmptyString(aconf->user) ? null : aconf->user;
@ -1124,21 +1320,55 @@ get_printable_conf(struct ConfItem *aconf, char **name, char **host,
*port = (int) aconf->port;
}
char *
get_user_ban_reason(struct ConfItem *aconf)
{
static char reasonbuf[BUFSIZE];
if (aconf->flags & CONF_FLAGS_TEMPORARY &&
(aconf->status == CONF_KILL || aconf->status == CONF_DLINE))
rb_snprintf(reasonbuf, sizeof reasonbuf,
"Temporary %c-line %d min. - ",
aconf->status == CONF_DLINE ? 'D' : 'K',
(int)((aconf->hold - aconf->created) / 60));
else
reasonbuf[0] = '\0';
if (aconf->passwd)
rb_strlcat(reasonbuf, aconf->passwd, sizeof reasonbuf);
else
rb_strlcat(reasonbuf, "No Reason", sizeof reasonbuf);
if (aconf->created)
{
rb_strlcat(reasonbuf, " (", sizeof reasonbuf);
rb_strlcat(reasonbuf, smalldate(aconf->created),
sizeof reasonbuf);
rb_strlcat(reasonbuf, ")", sizeof reasonbuf);
}
return reasonbuf;
}
void
get_printable_kline(struct Client *source_p, struct ConfItem *aconf,
char **host, char **reason,
char **user, char **oper_reason)
{
static char null[] = "<NULL>";
static char operreasonbuf[BUFSIZE];
*host = EmptyString(aconf->host) ? null : aconf->host;
*reason = EmptyString(aconf->passwd) ? null : aconf->passwd;
*user = EmptyString(aconf->user) ? null : aconf->user;
*reason = get_user_ban_reason(aconf);
if(EmptyString(aconf->spasswd) || !IsOper(source_p))
if(!IsOper(source_p))
*oper_reason = NULL;
else
*oper_reason = aconf->spasswd;
{
rb_snprintf(operreasonbuf, sizeof operreasonbuf, "%s%s(%s)",
EmptyString(aconf->spasswd) ? "" : aconf->spasswd,
EmptyString(aconf->spasswd) ? "" : " ",
aconf->info.oper);
*oper_reason = operreasonbuf;
}
}
/*

View File

@ -651,6 +651,7 @@ valid_temp_time(const char *p)
return(result * 60);
}
/* Propagated bans are expired elsewhere. */
static void
expire_temp_rxlines(void *unused)
{
@ -663,6 +664,8 @@ expire_temp_rxlines(void *unused)
{
aconf = ptr->data;
if(aconf->lifetime != 0)
continue;
if(aconf->hold && aconf->hold <= rb_current_time())
{
if(ConfigFileEntry.tkline_expire_notices)
@ -680,6 +683,8 @@ expire_temp_rxlines(void *unused)
{
aconf = ptr->data;
if(aconf->lifetime != 0)
continue;
if(aconf->hold && aconf->hold <= rb_current_time())
{
if(ConfigFileEntry.tkline_expire_notices)
@ -695,6 +700,8 @@ expire_temp_rxlines(void *unused)
{
aconf = ptr->data;
if(aconf->lifetime != 0)
continue;
if(aconf->hold && aconf->hold <= rb_current_time())
{
if(ConfigFileEntry.tkline_expire_notices)

View File

@ -89,6 +89,7 @@ struct Capability captab[] = {
{ "SAVE", CAP_SAVE },
{ "EUID", CAP_EUID },
{ "EOPMOD", CAP_EOPMOD },
{ "BAN", CAP_BAN },
{0, 0}
};
@ -392,6 +393,67 @@ send_capabilities(struct Client *client_p, int cap_can_send)
sendto_one(client_p, "CAPAB :%s", msgbuf);
}
static void
burst_ban(struct Client *client_p)
{
rb_dlink_node *ptr;
struct ConfItem *aconf;
const char *type, *oper;
/* +5 for !,@,{,} and null */
char operbuf[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
char *p;
size_t melen;
melen = strlen(me.name);
RB_DLINK_FOREACH(ptr, prop_bans.head)
{
aconf = ptr->data;
/* Skip expired stuff. */
if(aconf->lifetime < rb_current_time())
continue;
switch(aconf->status & ~CONF_ILLEGAL)
{
case CONF_KILL: type = "K"; break;
case CONF_DLINE: type = "D"; break;
case CONF_XLINE: type = "X"; break;
case CONF_RESV_NICK: type = "R"; break;
case CONF_RESV_CHANNEL: type = "R"; break;
default:
continue;
}
oper = aconf->info.oper;
if(aconf->flags & CONF_FLAGS_MYOPER)
{
/* Our operator{} names may not be meaningful
* to other servers, so rewrite to our server
* name.
*/
rb_strlcpy(operbuf, aconf->info.oper, sizeof buf);
p = strrchr(operbuf, '{');
if (p != NULL &&
operbuf + sizeof operbuf - p > (ptrdiff_t)(melen + 2))
{
memcpy(p + 1, me.name, melen);
p[melen + 1] = '}';
p[melen + 2] = '\0';
oper = operbuf;
}
}
sendto_one(client_p, ":%s BAN %s %s %s %lu %d %d %s :%s%s%s",
me.id,
type,
aconf->user ? aconf->user : "*", aconf->host,
(unsigned long)aconf->created,
(int)(aconf->hold - aconf->created),
(int)(aconf->lifetime - aconf->created),
oper,
aconf->passwd,
aconf->spasswd ? "|" : "",
aconf->spasswd ? aconf->spasswd : "");
}
}
/* burst_modes_TS6()
*
* input - client to burst to, channel name, list to burst, mode flag
@ -881,6 +943,9 @@ server_estab(struct Client *client_p)
target_p->serv->fullcaps);
}
if(IsCapable(client_p, CAP_BAN))
burst_ban(client_p);
burst_TS6(client_p);
/* Always send a PING after connect burst is done */

View File

@ -336,7 +336,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
}
/* dont replace username if its supposed to be spoofed --fl */
if(!IsConfDoSpoofIp(aconf) || !strchr(aconf->name, '@'))
if(!IsConfDoSpoofIp(aconf) || !strchr(aconf->info.name, '@'))
{
p = username;