Automated merge with ssh://shadowircd/uranium/shadowircd/
This commit is contained in:
commit
0068a2a2e2
|
@ -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
|
||||
|
|
4
CREDITS
4
CREDITS
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[]);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
246
modules/m_resv.c
246
modules/m_resv.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -76,6 +76,7 @@ SRCS = \
|
|||
monitor.c \
|
||||
newconf.c \
|
||||
numeric.c \
|
||||
operhash.c \
|
||||
packet.c \
|
||||
parse.c \
|
||||
privilege.c \
|
||||
|
|
|
@ -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])
|
||||
{
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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(<ime);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
258
src/s_conf.c
258
src/s_conf.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
|
|
65
src/s_serv.c
65
src/s_serv.c
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue