ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_kline.c
Revision: 7330
Committed: Fri Feb 19 17:50:13 2016 UTC (9 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 10419 byte(s)
Log Message:
- Now that we got time_t to work nicely on openbsd with snprintf's conversion specifiers,
  we ran into a similiar issue on Raspbian/ARMv7's time_t which is of signed 32 bit and
  doesn't cope at all with %j. Instead of doing tricks, get rid of time_t everywhere and
  forever and use uintmax_t instead which has at least a 'standardized' conversion specifier
  associated with it.

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2016 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 /*! \file m_kline.c
23 * \brief Includes required functions for processing the KLINE 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 "ircd.h"
32 #include "conf.h"
33 #include "conf_cluster.h"
34 #include "conf_shared.h"
35 #include "hostmask.h"
36 #include "numeric.h"
37 #include "log.h"
38 #include "misc.h"
39 #include "send.h"
40 #include "server.h"
41 #include "parse.h"
42 #include "modules.h"
43 #include "memory.h"
44
45
46 static void
47 kline_check(struct AddressRec *arec)
48 {
49 dlink_node *node = NULL, *node_next = NULL;
50
51 DLINK_FOREACH_SAFE(node, node_next, local_client_list.head)
52 {
53 struct Client *client_p = node->data;
54
55 if (IsDead(client_p))
56 continue;
57
58 if (match(arec->username, client_p->username))
59 continue;
60
61 switch (arec->masktype)
62 {
63 case HM_IPV4:
64 if (client_p->connection->aftype == AF_INET)
65 if (match_ipv4(&client_p->connection->ip, &arec->Mask.ipa.addr, arec->Mask.ipa.bits))
66 conf_try_ban(client_p, CLIENT_BAN_KLINE, arec->conf->reason);
67 break;
68 case HM_IPV6:
69 if (client_p->connection->aftype == AF_INET6)
70 if (match_ipv6(&client_p->connection->ip, &arec->Mask.ipa.addr, arec->Mask.ipa.bits))
71 conf_try_ban(client_p, CLIENT_BAN_KLINE, arec->conf->reason);
72 break;
73 default: /* HM_HOST */
74 if (!match(arec->Mask.hostname, client_p->host) || !match(arec->Mask.hostname, client_p->sockhost))
75 conf_try_ban(client_p, CLIENT_BAN_KLINE, arec->conf->reason);
76 break;
77 }
78 }
79 }
80
81 /* apply_tkline()
82 *
83 * inputs -
84 * output - NONE
85 * side effects - tkline as given is placed
86 */
87 static void
88 kline_add(struct Client *source_p, const char *user, const char *host,
89 const char *reason, uintmax_t duration)
90 {
91 char buf[IRCD_BUFSIZE];
92
93 if (duration)
94 snprintf(buf, sizeof(buf), "Temporary K-line %ju min. - %.*s (%s)",
95 duration / 60, REASONLEN, reason, date_iso8601(0));
96 else
97 snprintf(buf, sizeof(buf), "%.*s (%s)", REASONLEN, reason, date_iso8601(0));
98
99 struct MaskItem *conf = conf_make(CONF_KLINE);
100 conf->host = xstrdup(host);
101 conf->user = xstrdup(user);
102 conf->setat = CurrentTime;
103 conf->reason = xstrdup(buf);
104 SetConfDatabase(conf);
105
106 if (duration)
107 {
108 conf->until = CurrentTime + duration;
109
110 if (IsClient(source_p))
111 sendto_one_notice(source_p, &me, ":Added temporary %ju min. K-Line [%s@%s]",
112 duration / 60, conf->user, conf->host);
113
114 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
115 "%s added temporary %ju min. K-Line for [%s@%s] [%s]",
116 get_oper_name(source_p), duration / 60,
117 conf->user, conf->host,
118 conf->reason);
119 ilog(LOG_TYPE_KLINE, "%s added temporary %ju min. K-Line for [%s@%s] [%s]",
120 get_oper_name(source_p), duration / 60,
121 conf->user, conf->host, conf->reason);
122 }
123 else
124 {
125 if (IsClient(source_p))
126 sendto_one_notice(source_p, &me, ":Added K-Line [%s@%s]",
127 conf->user, conf->host);
128
129 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
130 "%s added K-Line for [%s@%s] [%s]",
131 get_oper_name(source_p),
132 conf->user, conf->host, conf->reason);
133 ilog(LOG_TYPE_KLINE, "%s added K-Line for [%s@%s] [%s]",
134 get_oper_name(source_p), conf->user, conf->host, conf->reason);
135 }
136
137 kline_check(add_conf_by_address(CONF_KLINE, conf));
138 }
139
140 /* already_placed_kline()
141 * inputs - user to complain to, username & host to check for
142 * outputs - returns 1 on existing K-line, 0 if doesn't exist
143 * side effects - notifies source_p if the K-line already exists
144 */
145 /*
146 * Note: This currently works if the new K-line is a special case of an
147 * existing K-line, but not the other way round. To do that we would
148 * have to walk the hash and check every existing K-line. -A1kmm.
149 */
150 static int
151 already_placed_kline(struct Client *source_p, const char *user, const char *host)
152 {
153 struct irc_ssaddr iphost, *piphost;
154 struct MaskItem *conf = NULL;
155 int t = 0;
156 int aftype = 0;
157
158 if ((t = parse_netmask(host, &iphost, NULL)) != HM_HOST)
159 {
160 if (t == HM_IPV6)
161 aftype = AF_INET6;
162 else
163 aftype = AF_INET;
164
165 piphost = &iphost;
166 }
167 else
168 piphost = NULL;
169
170 if ((conf = find_conf_by_address(host, piphost, CONF_KLINE, aftype, user, NULL, 0)))
171 {
172 if (IsClient(source_p))
173 sendto_one_notice(source_p, &me, ":[%s@%s] already K-Lined by [%s@%s] - %s",
174 user, host, conf->user, conf->host, conf->reason);
175 return 1;
176 }
177
178 return 0;
179 }
180
181 /* mo_kline()
182 *
183 * inputs - pointer to server
184 * - pointer to client
185 * - parameter count
186 * - parameter list
187 * output -
188 * side effects - k line is added
189 */
190 static int
191 mo_kline(struct Client *source_p, int parc, char *parv[])
192 {
193 char *reason = NULL;
194 char *user = NULL;
195 char *host = NULL;
196 char *target_server = NULL;
197 uintmax_t duration = 0;
198 int bits = 0;
199
200 if (!HasOFlag(source_p, OPER_FLAG_KLINE))
201 {
202 sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "kline");
203 return 0;
204 }
205
206 if (!parse_aline("KLINE", source_p, parc, parv, AWILD, &user, &host,
207 &duration, &target_server, &reason))
208 return 0;
209
210 if (target_server)
211 {
212 sendto_match_servs(source_p, target_server, CAPAB_KLN, "KLINE %s %ju %s %s :%s",
213 target_server, duration,
214 user, host, reason);
215
216 /* Allow ON to apply local kline as well if it matches */
217 if (match(target_server, me.name))
218 return 0;
219 }
220 else
221 cluster_distribute(source_p, "KLINE", CAPAB_KLN, CLUSTER_KLINE,
222 "%ju %s %s :%s", duration, user, host, reason);
223
224 if (already_placed_kline(source_p, user, host))
225 return 0;
226
227 switch (parse_netmask(host, NULL, &bits))
228 {
229 case HM_IPV4:
230 if ((unsigned int)bits < ConfigGeneral.kline_min_cidr)
231 {
232 sendto_one_notice(source_p, &me, ":For safety, bitmasks less than %u require conf access.",
233 ConfigGeneral.kline_min_cidr);
234 return 0;
235 }
236
237 break;
238 case HM_IPV6:
239 if ((unsigned int)bits < ConfigGeneral.kline_min_cidr6)
240 {
241 sendto_one_notice(source_p, &me, ":For safety, bitmasks less than %u require conf access.",
242 ConfigGeneral.kline_min_cidr6);
243 return 0;
244 }
245
246 break;
247 default: /* HM_HOST */
248 break;
249 }
250
251 kline_add(source_p, user, host, reason, duration);
252 return 0;
253 }
254
255 /*! \brief KLINE command handler
256 *
257 * \param source_p Pointer to allocated Client struct from which the message
258 * originally comes from. This can be a local or remote client.
259 * \param parc Integer holding the number of supplied arguments.
260 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
261 * pointers.
262 * \note Valid arguments for this command are:
263 * - parv[0] = command
264 * - parv[1] = target server mask
265 * - parv[2] = duration in seconds
266 * - parv[3] = user mask
267 * - parv[4] = host mask
268 * - parv[5] = reason
269 */
270 static int
271 ms_kline(struct Client *source_p, int parc, char *parv[])
272 {
273 uintmax_t duration = 0;
274 const char *user, *host, *reason;
275 int bits = 0;
276
277 if (parc != 6 || EmptyString(parv[5]))
278 return 0;
279
280 sendto_match_servs(source_p, parv[1], CAPAB_KLN, "KLINE %s %s %s %s :%s",
281 parv[1], parv[2], parv[3], parv[4], parv[5]);
282
283 if (match(parv[1], me.name))
284 return 0;
285
286 duration = valid_tkline(parv[2], TK_SECONDS);
287 user = parv[3];
288 host = parv[4];
289 reason = parv[5];
290
291 if (HasFlag(source_p, FLAGS_SERVICE) ||
292 shared_find(SHARED_KLINE, source_p->servptr->name,
293 source_p->username, source_p->host))
294 {
295 if (!valid_wild_card(source_p, 2, user, host))
296 return 0;
297
298 if (already_placed_kline(source_p, user, host))
299 return 0;
300
301 switch (parse_netmask(host, NULL, &bits))
302 {
303 case HM_IPV4:
304 if ((unsigned int)bits < ConfigGeneral.kline_min_cidr)
305 {
306 if (IsClient(source_p))
307 sendto_one_notice(source_p, &me, ":For safety, bitmasks less than %u require conf access.",
308 ConfigGeneral.kline_min_cidr);
309 return 0;
310 }
311
312 break;
313 case HM_IPV6:
314 if ((unsigned int)bits < ConfigGeneral.kline_min_cidr6)
315 {
316 if (IsClient(source_p))
317 sendto_one_notice(source_p, &me, ":For safety, bitmasks less than %u require conf access.",
318 ConfigGeneral.kline_min_cidr6);
319 return 0;
320 }
321
322 break;
323 default: /* HM_HOST */
324 break;
325 }
326
327 kline_add(source_p, user, host, reason, duration);
328 }
329
330 return 0;
331 }
332
333 static struct Message kline_msgtab =
334 {
335 .cmd = "KLINE",
336 .args_min = 2,
337 .args_max = MAXPARA,
338 .handlers[UNREGISTERED_HANDLER] = m_unregistered,
339 .handlers[CLIENT_HANDLER] = m_not_oper,
340 .handlers[SERVER_HANDLER] = ms_kline,
341 .handlers[ENCAP_HANDLER] = m_ignore,
342 .handlers[OPER_HANDLER] = mo_kline
343 };
344
345 static void
346 module_init(void)
347 {
348 mod_add_cmd(&kline_msgtab);
349 add_capability("KLN", CAPAB_KLN);
350 }
351
352 static void
353 module_exit(void)
354 {
355 mod_del_cmd(&kline_msgtab);
356 delete_capability("KLN");
357 }
358
359 struct module module_entry =
360 {
361 .version = "$Revision$",
362 .modinit = module_init,
363 .modexit = module_exit,
364 };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision