1 |
/* |
2 |
* ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) |
3 |
* |
4 |
* Copyright (c) 1997-2014 ircd-hybrid development team |
5 |
* |
6 |
* This program is free software; you can redistribute it and/or modify |
7 |
* it under the terms of the GNU General Public License as published by |
8 |
* the Free Software Foundation; either version 2 of the License, or |
9 |
* (at your option) any later version. |
10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
* GNU General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the GNU General Public License |
17 |
* along with this program; if not, write to the Free Software |
18 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
19 |
* USA |
20 |
*/ |
21 |
|
22 |
/*! \file m_dline.c |
23 |
* \brief Includes required functions for processing the DLINE command. |
24 |
* \version $Id$ |
25 |
*/ |
26 |
|
27 |
#include "stdinc.h" |
28 |
#include "list.h" |
29 |
#include "client.h" |
30 |
#include "irc_string.h" |
31 |
#include "conf.h" |
32 |
#include "ircd.h" |
33 |
#include "hostmask.h" |
34 |
#include "numeric.h" |
35 |
#include "log.h" |
36 |
#include "misc.h" |
37 |
#include "send.h" |
38 |
#include "hash.h" |
39 |
#include "server.h" |
40 |
#include "parse.h" |
41 |
#include "modules.h" |
42 |
#include "conf_db.h" |
43 |
#include "memory.h" |
44 |
|
45 |
|
46 |
/* apply_tdline() |
47 |
* |
48 |
* inputs - |
49 |
* output - NONE |
50 |
* side effects - tkline as given is placed |
51 |
*/ |
52 |
static void |
53 |
apply_dline(struct Client *source_p, struct MaskItem *conf, |
54 |
time_t tkline_time) |
55 |
{ |
56 |
if (tkline_time) |
57 |
{ |
58 |
conf->until = CurrentTime + tkline_time; |
59 |
sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, |
60 |
"%s added temporary %d min. D-Line for [%s] [%s]", |
61 |
get_oper_name(source_p), tkline_time/60, |
62 |
conf->host, conf->reason); |
63 |
sendto_one_notice(source_p, &me, ":Added temporary %d min. D-Line [%s]", |
64 |
tkline_time/60, conf->host); |
65 |
ilog(LOG_TYPE_DLINE, "%s added temporary %d min. D-Line for [%s] [%s]", |
66 |
get_oper_name(source_p), tkline_time/60, conf->host, conf->reason); |
67 |
} |
68 |
else |
69 |
{ |
70 |
sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, |
71 |
"%s added D-Line for [%s] [%s]", |
72 |
get_oper_name(source_p), conf->host, conf->reason); |
73 |
sendto_one_notice(source_p, &me, ":Added D-Line [%s]", conf->host); |
74 |
ilog(LOG_TYPE_DLINE, "%s added D-Line for [%s] [%s]", |
75 |
get_oper_name(source_p), conf->host, conf->reason); |
76 |
|
77 |
} |
78 |
|
79 |
SetConfDatabase(conf); |
80 |
conf->setat = CurrentTime; |
81 |
add_conf_by_address(CONF_DLINE, conf); |
82 |
rehashed_klines = 1; |
83 |
} |
84 |
|
85 |
/* mo_dline() |
86 |
* |
87 |
* inputs - pointer to server |
88 |
* - pointer to client |
89 |
* - parameter count |
90 |
* - parameter list |
91 |
* output - |
92 |
* side effects - D line is added |
93 |
* |
94 |
*/ |
95 |
static int |
96 |
mo_dline(struct Client *source_p, int parc, char *parv[]) |
97 |
{ |
98 |
char def_reason[] = CONF_NOREASON; |
99 |
char *dlhost = NULL, *reason = NULL; |
100 |
char *target_server = NULL; |
101 |
const char *creason; |
102 |
const struct Client *target_p = NULL; |
103 |
struct irc_ssaddr daddr; |
104 |
struct MaskItem *conf=NULL; |
105 |
time_t tkline_time=0; |
106 |
int bits = 0, aftype = 0, t = 0; |
107 |
const char *current_date = NULL; |
108 |
char hostip[HOSTIPLEN + 1]; |
109 |
char buffer[IRCD_BUFSIZE]; |
110 |
|
111 |
if (!HasOFlag(source_p, OPER_FLAG_DLINE)) |
112 |
{ |
113 |
sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "dline"); |
114 |
return 0; |
115 |
} |
116 |
|
117 |
if (parse_aline("DLINE", source_p, parc, parv, AWILD, &dlhost, |
118 |
NULL, &tkline_time, &target_server, &reason) < 0) |
119 |
return 0; |
120 |
|
121 |
if (target_server) |
122 |
{ |
123 |
sendto_match_servs(source_p, target_server, CAP_DLN, "DLINE %s %lu %s :%s", |
124 |
target_server, (unsigned long)tkline_time, |
125 |
dlhost, reason); |
126 |
|
127 |
/* Allow ON to apply local kline as well if it matches */ |
128 |
if (match(target_server, me.name)) |
129 |
return 0; |
130 |
} |
131 |
else |
132 |
cluster_a_line(source_p, "DLINE", CAP_DLN, SHARED_DLINE, |
133 |
"%d %s :%s", tkline_time, dlhost, reason); |
134 |
|
135 |
if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) |
136 |
{ |
137 |
if ((target_p = find_chasing(source_p, dlhost)) == NULL) |
138 |
return 0; /* find_chasing sends ERR_NOSUCHNICK */ |
139 |
|
140 |
if (!MyConnect(target_p)) |
141 |
{ |
142 |
sendto_one_notice(source_p, &me, ":Cannot DLINE nick on another server"); |
143 |
return 0; |
144 |
} |
145 |
|
146 |
if (IsExemptKline(target_p)) |
147 |
{ |
148 |
sendto_one_notice(source_p, &me, ":%s is E-lined", |
149 |
target_p->name); |
150 |
return 0; |
151 |
} |
152 |
|
153 |
getnameinfo((struct sockaddr *)&target_p->localClient->ip, |
154 |
target_p->localClient->ip.ss_len, hostip, |
155 |
sizeof(hostip), NULL, 0, NI_NUMERICHOST); |
156 |
dlhost = hostip; |
157 |
t = parse_netmask(dlhost, NULL, &bits); |
158 |
assert(t == HM_IPV4 || t == HM_IPV6); |
159 |
} |
160 |
|
161 |
if (bits < 8) |
162 |
{ |
163 |
sendto_one_notice(source_p, &me, ":For safety, bitmasks less than 8 require conf access."); |
164 |
return 0; |
165 |
} |
166 |
|
167 |
#ifdef IPV6 |
168 |
if (t == HM_IPV6) |
169 |
aftype = AF_INET6; |
170 |
else |
171 |
#endif |
172 |
aftype = AF_INET; |
173 |
|
174 |
parse_netmask(dlhost, &daddr, NULL); |
175 |
|
176 |
if ((conf = find_dline_conf(&daddr, aftype))) |
177 |
{ |
178 |
creason = conf->reason ? conf->reason : def_reason; |
179 |
|
180 |
if (IsConfExemptKline(conf)) |
181 |
sendto_one_notice(source_p, &me, ":[%s] is (E)d-lined by [%s] - %s", |
182 |
dlhost, conf->host, creason); |
183 |
else |
184 |
sendto_one_notice(source_p, &me, ":[%s] already D-lined by [%s] - %s", |
185 |
dlhost, conf->host, creason); |
186 |
return 0; |
187 |
} |
188 |
|
189 |
current_date = smalldate(0); |
190 |
|
191 |
if (!valid_comment(source_p, reason, 1)) |
192 |
return 0; |
193 |
|
194 |
conf = conf_make(CONF_DLINE); |
195 |
conf->host = xstrdup(dlhost); |
196 |
|
197 |
if (tkline_time) |
198 |
snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)", |
199 |
(int)(tkline_time/60), reason, current_date); |
200 |
else |
201 |
snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date); |
202 |
|
203 |
conf->reason = xstrdup(buffer); |
204 |
apply_dline(source_p, conf, tkline_time); |
205 |
rehashed_klines = 1; |
206 |
return 0; |
207 |
} |
208 |
|
209 |
static int |
210 |
ms_dline(struct Client *source_p, int parc, char *parv[]) |
211 |
{ |
212 |
char def_reason[] = CONF_NOREASON; |
213 |
char *dlhost, *reason; |
214 |
const char *creason; |
215 |
const struct Client *target_p = NULL; |
216 |
struct irc_ssaddr daddr; |
217 |
struct MaskItem *conf=NULL; |
218 |
time_t tkline_time=0; |
219 |
int bits = 0, aftype = 0, t = 0; |
220 |
const char *current_date = NULL; |
221 |
char hostip[HOSTIPLEN + 1]; |
222 |
char buffer[IRCD_BUFSIZE]; |
223 |
|
224 |
if (parc != 5 || EmptyString(parv[4])) |
225 |
return 0; |
226 |
|
227 |
/* parv[0] parv[1] parv[2] parv[3] parv[4] */ |
228 |
/* oper target_server tkline_time host reason */ |
229 |
sendto_match_servs(source_p, parv[1], CAP_DLN, |
230 |
"DLINE %s %s %s :%s", |
231 |
parv[1], parv[2], parv[3], parv[4]); |
232 |
|
233 |
if (match(parv[1], me.name)) |
234 |
return 0; |
235 |
|
236 |
tkline_time = valid_tkline(parv[2], TK_SECONDS); |
237 |
dlhost = parv[3]; |
238 |
reason = parv[4]; |
239 |
|
240 |
if (HasFlag(source_p, FLAGS_SERVICE) || |
241 |
find_matching_name_conf(CONF_ULINE, source_p->servptr->name, |
242 |
source_p->username, source_p->host, |
243 |
SHARED_DLINE)) |
244 |
{ |
245 |
if (!IsClient(source_p)) |
246 |
return 0; |
247 |
|
248 |
if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) |
249 |
{ |
250 |
if ((target_p = find_chasing(source_p, dlhost)) == NULL) |
251 |
return 0; /* find_chasing sends ERR_NOSUCHNICK */ |
252 |
|
253 |
if (!MyConnect(target_p)) |
254 |
{ |
255 |
sendto_one_notice(source_p, &me, ":Cannot DLINE nick on another server"); |
256 |
return 0; |
257 |
} |
258 |
|
259 |
if (IsExemptKline(target_p)) |
260 |
{ |
261 |
sendto_one_notice(source_p, &me, ":%s is E-lined", target_p->name); |
262 |
return 0; |
263 |
} |
264 |
|
265 |
getnameinfo((struct sockaddr *)&target_p->localClient->ip, |
266 |
target_p->localClient->ip.ss_len, hostip, |
267 |
sizeof(hostip), NULL, 0, NI_NUMERICHOST); |
268 |
dlhost = hostip; |
269 |
t = parse_netmask(dlhost, NULL, &bits); |
270 |
assert(t == HM_IPV4 || t == HM_IPV6); |
271 |
} |
272 |
|
273 |
if (bits < 8) |
274 |
{ |
275 |
sendto_one_notice(source_p, &me, ":For safety, bitmasks less than 8 require conf access."); |
276 |
return 0; |
277 |
} |
278 |
|
279 |
#ifdef IPV6 |
280 |
if (t == HM_IPV6) |
281 |
aftype= AF_INET6; |
282 |
else |
283 |
#endif |
284 |
aftype = AF_INET; |
285 |
|
286 |
parse_netmask(dlhost, &daddr, NULL); |
287 |
|
288 |
if ((conf = find_dline_conf(&daddr, aftype))) |
289 |
{ |
290 |
creason = conf->reason ? conf->reason : def_reason; |
291 |
if (IsConfExemptKline(conf)) |
292 |
sendto_one_notice(source_p, &me, ":[%s] is (E)d-lined by [%s] - %s", |
293 |
dlhost, conf->host, creason); |
294 |
else |
295 |
sendto_one_notice(source_p, &me, ":[%s] already D-lined by [%s] - %s", |
296 |
dlhost, conf->host, creason); |
297 |
return 0; |
298 |
} |
299 |
|
300 |
current_date = smalldate(0); |
301 |
|
302 |
if (!valid_comment(source_p, reason, 1)) |
303 |
return 0; |
304 |
|
305 |
conf = conf_make(CONF_DLINE); |
306 |
conf->host = xstrdup(dlhost); |
307 |
|
308 |
if (tkline_time) |
309 |
snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)", |
310 |
(int)(tkline_time/60), reason, current_date); |
311 |
else |
312 |
snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date); |
313 |
|
314 |
conf->reason = xstrdup(buffer); |
315 |
apply_dline(source_p, conf, tkline_time); |
316 |
rehashed_klines = 1; |
317 |
} |
318 |
|
319 |
return 0; |
320 |
} |
321 |
|
322 |
static struct Message dline_msgtab = |
323 |
{ |
324 |
"DLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0, |
325 |
{ m_unregistered, m_not_oper, ms_dline, m_ignore, mo_dline, m_ignore } |
326 |
}; |
327 |
|
328 |
static void |
329 |
module_init(void) |
330 |
{ |
331 |
mod_add_cmd(&dline_msgtab); |
332 |
add_capability("DLN", CAP_DLN, 1); |
333 |
} |
334 |
|
335 |
static void |
336 |
module_exit(void) |
337 |
{ |
338 |
mod_del_cmd(&dline_msgtab); |
339 |
delete_capability("DLN"); |
340 |
} |
341 |
|
342 |
struct module module_entry = |
343 |
{ |
344 |
.node = { NULL, NULL, NULL }, |
345 |
.name = NULL, |
346 |
.version = "$Revision$", |
347 |
.handle = NULL, |
348 |
.modinit = module_init, |
349 |
.modexit = module_exit, |
350 |
.flags = 0 |
351 |
}; |