]> jfr.im git - solanum.git/blame - modules/core/m_ban.c
Remove +/- from the BAN message, instead indicating unban with duration=0.
[solanum.git] / modules / core / m_ban.c
CommitLineData
431a1a27
JT
1/*
2 * charybdis: An advanced ircd.
3 * m_ban.c: Propagates network bans across servers.
4 *
5 * Copyright (C) 2010 Jilles Tjoelker
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * 1.Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2.Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "stdinc.h"
31#include "send.h"
32#include "client.h"
33#include "common.h"
34#include "config.h"
35#include "ircd.h"
36#include "match.h"
37#include "s_conf.h"
38#include "msg.h"
39#include "modules.h"
40#include "hash.h"
41#include "s_serv.h"
42#include "operhash.h"
43#include "reject.h"
44#include "hostmask.h"
45
46static int ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
47
48struct Message ban_msgtab = {
49 "BAN", 0, 0, 0, MFLG_SLOW,
cedb7d05 50 {mg_unreg, mg_ignore, {ms_ban, 9}, {ms_ban, 9}, mg_ignore, mg_ignore}
431a1a27
JT
51};
52
53mapi_clist_av1 ban_clist[] = { &ban_msgtab, NULL };
54DECLARE_MODULE_AV1(ban, NULL, NULL, ban_clist, NULL, NULL, "$Revision: 1349 $");
55
56/* ms_ban()
57 *
cedb7d05
JT
58 * parv[1] - type
59 * parv[2] - username mask or *
60 * parv[3] - hostname mask
61 * parv[4] - creation TS
62 * parv[5] - duration (relative to creation)
63 * parv[6] - lifetime (relative to creation)
64 * parv[7] - oper or *
65 * parv[8] - reason (possibly with |operreason)
431a1a27
JT
66 */
67static int
68ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
69{
70 rb_dlink_node *ptr;
71 struct ConfItem *aconf;
72 unsigned int ntype;
73 const char *oper, *stype;
74 time_t created, hold, lifetime;
75 char *p;
76 int act;
77
cedb7d05 78 if (strlen(parv[1]) != 1)
431a1a27
JT
79 {
80 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
81 "Unknown BAN type %s from %s",
cedb7d05 82 parv[1], source_p->name);
431a1a27
JT
83 return 0;
84 }
cedb7d05 85 switch (parv[1][0])
431a1a27
JT
86 {
87 case 'K':
88 ntype = CONF_KILL;
89 stype = "K-Line";
90 break;
91 default:
92 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
93 "Unknown BAN type %s from %s",
cedb7d05 94 parv[1], source_p->name);
431a1a27
JT
95 return 0;
96 }
cedb7d05
JT
97 created = atol(parv[4]);
98 hold = created + atoi(parv[5]);
99 lifetime = created + atoi(parv[6]);
100 if (!strcmp(parv[7], "*"))
431a1a27
JT
101 oper = IsServer(source_p) ? source_p->name : get_oper_name(source_p);
102 else
cedb7d05
JT
103 oper = parv[7];
104 ptr = find_prop_ban(ntype, parv[2], parv[3]);
431a1a27
JT
105 if (ptr != NULL)
106 {
107 aconf = ptr->data;
108 if (aconf->created >= created)
109 {
110 if (IsPerson(source_p))
111 sendto_one_notice(source_p,
112 ":Your %s [%s%s%s] has been superseded",
113 stype,
114 aconf->user ? aconf->user : "",
115 aconf->user ? "@" : "",
116 aconf->host);
117 return 0;
118 }
cedb7d05
JT
119 act = !(aconf->status & CONF_ILLEGAL) || (hold != created &&
120 hold > rb_current_time());
431a1a27
JT
121 if (lifetime > aconf->lifetime)
122 aconf->lifetime = lifetime;
123 /* already expired, hmm */
124 if (aconf->lifetime <= rb_current_time())
125 return 0;
126 deactivate_conf(aconf, ptr);
127 rb_free(aconf->user);
128 aconf->user = NULL;
129 rb_free(aconf->host);
130 aconf->host = NULL;
131 operhash_delete(aconf->info.oper);
132 aconf->info.oper = NULL;
133 rb_free(aconf->passwd);
134 aconf->passwd = NULL;
135 rb_free(aconf->spasswd);
136 aconf->spasswd = NULL;
137 }
138 else
139 {
140 aconf = make_conf();
141 aconf->status = CONF_ILLEGAL | ntype;
142 aconf->lifetime = lifetime;
143 rb_dlinkAddAlloc(aconf, &prop_bans);
cedb7d05 144 act = hold != created && hold > rb_current_time();
431a1a27
JT
145 }
146 aconf->flags &= ~CONF_FLAGS_MYOPER;
147 aconf->flags |= CONF_FLAGS_TEMPORARY;
cedb7d05
JT
148 aconf->user = ntype == CONF_KILL ? rb_strdup(parv[2]) : NULL;
149 aconf->host = rb_strdup(parv[3]);
431a1a27
JT
150 aconf->info.oper = operhash_add(oper);
151 aconf->created = created;
152 aconf->hold = hold;
153 p = strchr(parv[parc - 1], '|');
154 if (p == NULL)
155 aconf->passwd = rb_strdup(parv[parc - 1]);
156 else
157 {
158 aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1);
159 aconf->spasswd = rb_strdup(p + 1);
160 }
cedb7d05 161 if (act && hold != created)
431a1a27
JT
162 {
163 /* Keep the notices in sync with modules/m_kline.c etc. */
164 sendto_realops_snomask(SNO_GENERAL, L_ALL,
165 "%s added global %d min. %s%s%s for [%s%s%s] [%s]",
166 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
167 (hold - rb_current_time()) / 60,
168 stype,
cedb7d05
JT
169 strcmp(parv[7], "*") ? " from " : "",
170 strcmp(parv[7], "*") ? parv[7] : "",
431a1a27
JT
171 aconf->user ? aconf->user : "",
172 aconf->user ? "@" : "",
173 aconf->host,
174 parv[parc - 1]);
cedb7d05 175 ilog(L_KLINE, "%s %s %d %s %s %s", parv[1],
431a1a27
JT
176 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
177 (hold - rb_current_time()) / 60,
178 aconf->user, aconf->host,
179 parv[parc - 1]);
cedb7d05 180 aconf->status &= ~CONF_ILLEGAL;
431a1a27
JT
181 }
182 else if (act)
183 {
184 sendto_realops_snomask(SNO_GENERAL, L_ALL,
185 "%s has removed the global %s for: [%s%s%s]%s%s",
186 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
187 stype,
188 aconf->user ? aconf->user : "",
189 aconf->user ? "@" : "",
190 aconf->host,
cedb7d05
JT
191 strcmp(parv[7], "*") ? " on behalf of " : "",
192 strcmp(parv[7], "*") ? parv[7] : "");
193 ilog(L_KLINE, "U%s %s %s %s", parv[1],
431a1a27
JT
194 IsServer(source_p) ? source_p->name : get_oper_name(source_p),
195 aconf->user, aconf->host);
196 }
197 switch (ntype)
198 {
199 case CONF_KILL:
200 if (aconf->status & CONF_ILLEGAL)
201 remove_reject_mask(aconf->user, aconf->host);
202 else
203 {
204 add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
205 if(ConfigFileEntry.kline_delay ||
206 (IsServer(source_p) &&
207 !HasSentEob(source_p)))
208 {
209 if(kline_queued == 0)
210 {
211 rb_event_addonce("check_klines", check_klines_event, NULL,
212 ConfigFileEntry.kline_delay);
213 kline_queued = 1;
214 }
215 }
216 else
217 check_klines();
218 }
219 break;
220 }
221 sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
cedb7d05 222 ":%s BAN %s %s %s %s %s %s %s :%s",
431a1a27
JT
223 source_p->id,
224 parv[1],
225 parv[2],
226 parv[3],
227 parv[4],
228 parv[5],
229 parv[6],
230 parv[7],
431a1a27
JT
231 parv[parc - 1]);
232 return 0;
233}