]>
jfr.im git - solanum.git/blob - modules/core/m_ban.c
2 * charybdis: An advanced ircd.
3 * m_ban.c: Propagates network bans across servers.
5 * Copyright (C) 2010 Jilles Tjoelker
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
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.
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.
38 #include "s_newconf.h"
48 static const char ban_desc
[] = "Provides the TS6 BAN command for propagating network-wide bans";
50 static void m_ban(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[]);
51 static void ms_ban(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[]);
53 struct Message ban_msgtab
= {
55 {mg_unreg
, {m_ban
, 0}, {ms_ban
, 9}, {ms_ban
, 9}, mg_ignore
, {m_ban
, 0}}
58 mapi_clist_av1 ban_clist
[] = { &ban_msgtab
, NULL
};
60 DECLARE_MODULE_AV2(ban
, NULL
, NULL
, ban_clist
, NULL
, NULL
, NULL
, NULL
, ban_desc
);
63 m_ban(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
65 sendto_one_notice(source_p
, ":The BAN command is not user-accessible.");
66 sendto_one_notice(source_p
, ":To ban a user from a channel, see /QUOTE HELP CMODE");
67 if (IsOperGeneral(source_p
))
68 sendto_one_notice(source_p
, ":To ban a user from a server or from the network, see /QUOTE HELP KLINE");
74 * parv[2] - username mask or *
75 * parv[3] - hostname mask
76 * parv[4] - creation TS
77 * parv[5] - duration (relative to creation)
78 * parv[6] - lifetime (relative to creation)
80 * parv[8] - reason (possibly with |operreason)
83 ms_ban(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
86 struct ConfItem
*aconf
;
88 const char *oper
, *stype
;
89 time_t now
, created
, hold
, lifetime
;
94 now
= rb_current_time();
95 if (strlen(parv
[1]) != 1)
97 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
98 "Unknown BAN type %s from %s",
99 parv
[1], source_p
->name
);
113 ntype
= IsChannelName(parv
[3]) ? CONF_RESV_CHANNEL
:
118 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
119 "Unknown BAN type %s from %s",
120 parv
[1], source_p
->name
);
123 created
= atol(parv
[4]);
124 hold
= created
+ atoi(parv
[5]);
125 lifetime
= created
+ atoi(parv
[6]);
126 if (!strcmp(parv
[7], "*"))
127 oper
= IsServer(source_p
) ? source_p
->name
: get_oper_name(source_p
);
130 ptr
= find_prop_ban(ntype
, parv
[2], parv
[3]);
133 /* We already know about this ban mask. */
135 if (aconf
->created
> created
||
136 (aconf
->created
== created
&&
137 aconf
->lifetime
>= lifetime
))
139 if (IsPerson(source_p
))
140 sendto_one_notice(source_p
,
141 ":Your %s [%s%s%s] has been superseded",
143 aconf
->user
? aconf
->user
: "",
144 aconf
->user
? "@" : "",
148 /* act indicates if something happened (from the oper's
149 * point of view). This is the case if the ban was
150 * previously active (not deleted) or if the new ban
151 * is not a removal and not already expired.
153 act
= !(aconf
->status
& CONF_ILLEGAL
) || (hold
!= created
&&
155 if (lifetime
> aconf
->lifetime
)
156 aconf
->lifetime
= lifetime
;
157 /* already expired, hmm */
158 if (aconf
->lifetime
<= now
)
160 /* Deactivate, it will be reactivated later if appropriate. */
161 deactivate_conf(aconf
, ptr
, now
);
162 rb_free(aconf
->user
);
164 rb_free(aconf
->host
);
166 operhash_delete(aconf
->info
.oper
);
167 aconf
->info
.oper
= NULL
;
168 rb_free(aconf
->passwd
);
169 aconf
->passwd
= NULL
;
170 rb_free(aconf
->spasswd
);
171 aconf
->spasswd
= NULL
;
177 aconf
->status
= CONF_ILLEGAL
| ntype
;
178 aconf
->lifetime
= lifetime
;
179 rb_dlinkAddAlloc(aconf
, &prop_bans
);
180 act
= hold
!= created
&& hold
> now
;
182 aconf
->flags
&= ~CONF_FLAGS_MYOPER
;
183 aconf
->flags
|= CONF_FLAGS_TEMPORARY
;
184 aconf
->user
= ntype
== CONF_KILL
? rb_strdup(parv
[2]) : NULL
;
185 aconf
->host
= rb_strdup(parv
[3]);
186 aconf
->info
.oper
= operhash_add(oper
);
187 aconf
->created
= created
;
189 if (ntype
!= CONF_KILL
|| (p
= strchr(parv
[parc
- 1], '|')) == NULL
)
190 aconf
->passwd
= rb_strdup(parv
[parc
- 1]);
193 aconf
->passwd
= rb_strndup(parv
[parc
- 1], p
- parv
[parc
- 1] + 1);
194 aconf
->spasswd
= rb_strdup(p
+ 1);
196 /* The ban is fully filled in and in the prop_bans list
197 * but still deactivated. Now determine if it should be activated
198 * and send the server notices.
200 /* We only reject *@* and the like here.
201 * Otherwise malformed bans are fairly harmless and can be removed.
206 valid
= valid_wild_card(aconf
->user
, aconf
->host
);
208 case CONF_RESV_CHANNEL
:
212 valid
= valid_wild_card_simple(aconf
->host
);
215 if (act
&& hold
!= created
&& !valid
)
217 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
218 "Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters",
219 (int)((hold
- now
) / 60),
221 IsServer(source_p
) ? source_p
->name
: get_oper_name(source_p
),
222 strcmp(parv
[7], "*") ? " on behalf of " : "",
223 strcmp(parv
[7], "*") ? parv
[7] : "",
224 aconf
->user
? aconf
->user
: "",
225 aconf
->user
? "@" : "",
227 if(IsPerson(source_p
))
228 sendto_one_notice(source_p
,
229 ":Your %s [%s%s%s] has too few non-wildcard characters",
231 aconf
->user
? aconf
->user
: "",
232 aconf
->user
? "@" : "",
234 /* Propagate it, but do not apply it locally. */
236 else if (act
&& hold
!= created
)
238 /* Keep the notices in sync with modules/m_kline.c etc. */
239 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
240 "%s added global %d min. %s%s%s for [%s%s%s] [%s]",
241 IsServer(source_p
) ? source_p
->name
: get_oper_name(source_p
),
242 (int)((hold
- now
) / 60),
244 strcmp(parv
[7], "*") ? " from " : "",
245 strcmp(parv
[7], "*") ? parv
[7] : "",
246 aconf
->user
? aconf
->user
: "",
247 aconf
->user
? "@" : "",
250 ilog(L_KLINE
, "%s %s %d %s%s%s %s", parv
[1],
251 IsServer(source_p
) ? source_p
->name
: get_oper_name(source_p
),
252 (int)((hold
- now
) / 60),
253 aconf
->user
? aconf
->user
: "",
254 aconf
->user
? " " : "",
257 aconf
->status
&= ~CONF_ILLEGAL
;
261 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
262 "%s has removed the global %s for: [%s%s%s]%s%s",
263 IsServer(source_p
) ? source_p
->name
: get_oper_name(source_p
),
265 aconf
->user
? aconf
->user
: "",
266 aconf
->user
? "@" : "",
268 strcmp(parv
[7], "*") ? " on behalf of " : "",
269 strcmp(parv
[7], "*") ? parv
[7] : "");
270 ilog(L_KLINE
, "U%s %s %s%s %s", parv
[1],
271 IsServer(source_p
) ? source_p
->name
: get_oper_name(source_p
),
272 aconf
->user
? aconf
->user
: "",
273 aconf
->user
? " " : "",
276 /* If CONF_ILLEGAL is still set at this point, remove entries from the
277 * reject cache (for klines and xlines).
278 * If CONF_ILLEGAL is not set, add the ban to the type-specific data
279 * structure and take action on matched clients/channels.
284 if (aconf
->status
& CONF_ILLEGAL
)
285 remove_reject_mask(aconf
->user
, aconf
->host
);
288 add_conf_by_address(aconf
->host
, CONF_KILL
, aconf
->user
, NULL
, aconf
);
289 check_one_kline(aconf
);
293 if (aconf
->status
& CONF_ILLEGAL
)
294 remove_reject_mask(aconf
->host
, NULL
);
297 rb_dlinkAddAlloc(aconf
, &xline_conf_list
);
301 case CONF_RESV_CHANNEL
:
302 if (!(aconf
->status
& CONF_ILLEGAL
))
304 add_to_resv_hash(aconf
->host
, aconf
);
305 resv_chan_forcepart(aconf
->host
, aconf
->passwd
, hold
- now
);
309 if (!(aconf
->status
& CONF_ILLEGAL
))
310 rb_dlinkAddAlloc(aconf
, &resv_conf_list
);
313 sendto_server(client_p
, NULL
, CAP_BAN
|CAP_TS6
, NOCAPS
,
314 ":%s BAN %s %s %s %s %s %s %s :%s",