ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_xline.c
(Generate patch)

Comparing ircd-hybrid/trunk/modules/m_xline.c (file contents):
Revision 3347 by michael, Sun Apr 20 14:03:06 2014 UTC vs.
Revision 8670 by michael, Sat Nov 24 13:32:28 2018 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 2003-2014 ircd-hybrid development team
4 > *  Copyright (c) 2003-2018 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
# Line 15 | Line 15
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
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20   */
21  
22   /*! \file m_xline.c
23 < * \brief Includes required functions for processing the XLINE/UNXLINE command.
23 > * \brief Includes required functions for processing the XLINE command.
24   * \version $Id$
25   */
26  
# Line 30 | Line 30
30   #include "irc_string.h"
31   #include "ircd.h"
32   #include "conf.h"
33 + #include "conf_cluster.h"
34 + #include "conf_gecos.h"
35 + #include "conf_shared.h"
36   #include "numeric.h"
37   #include "log.h"
38 + #include "misc.h"
39   #include "send.h"
40 < #include "server.h"
40 > #include "server_capab.h"
41   #include "parse.h"
42   #include "modules.h"
39 #include "conf_db.h"
43   #include "memory.h"
44  
45  
46   static void
47 < check_xline(struct MaskItem *conf)
47 > xline_check(const struct GecosItem *gecos)
48   {
49 <  dlink_node *ptr = NULL, *ptr_next = NULL;
49 >  dlink_node *node, *node_next;
50  
51 <  DLINK_FOREACH_SAFE(ptr, ptr_next, local_client_list.head)
51 >  DLINK_FOREACH_SAFE(node, node_next, local_client_list.head)
52    {
53 <    struct Client *client_p = ptr->data;
53 >    struct Client *client_p = node->data;
54  
55      if (IsDead(client_p))
56        continue;
57  
58 <    if (!match(conf->name, client_p->username))
59 <      conf_try_ban(client_p, conf);
58 >    if (match(gecos->mask, client_p->info) == 0)
59 >      conf_try_ban(client_p, CLIENT_BAN_XLINE, gecos->reason);
60    }
61   }
62  
63 < /* static int remove_tkline_match(const char *host, const char *user)
63 > /* xline_handle()
64   *
65 < * Inputs:      gecos
66 < * Output:      returns YES on success, NO if no tkline removed.
67 < * Side effects: Any matching tklines are removed.
65 > * inputs       - client taking credit for xline, gecos, reason, xline type
66 > * outputs      - none
67 > * side effects - when successful, adds an xline to the conf
68   */
69 < static int
70 < remove_xline_match(const char *gecos)
69 > static void
70 > xline_handle(struct Client *source_p, struct aline_ctx *aline)
71   {
72 <  dlink_node *ptr = NULL, *next_ptr = NULL;
72 >  char buf[IRCD_BUFSIZE];
73  
74 <  DLINK_FOREACH_SAFE(ptr, next_ptr, xconf_items.head)
74 >  if (!HasFlag(source_p, FLAGS_SERVICE))
75    {
76 <    struct MaskItem *conf = ptr->data;
74 <
75 <    if (!IsConfDatabase(conf))
76 <      continue;
77 <
78 <    if (!irccmp(gecos, conf->name))
76 >    if (valid_wild_card_simple(aline->host) == false)
77      {
78 <      conf_free(conf);
79 <      return 1;
78 >      if (IsClient(source_p))
79 >        sendto_one_notice(source_p, &me, ":Please include at least %u non-wildcard characters with the xline",
80 >                          ConfigGeneral.min_nonwildcard_simple);
81 >      return;
82      }
83    }
84  
85 <  return 0;
86 < }
87 <
88 < static void
89 < remove_xline(struct Client *source_p, const char *gecos)
90 < {
91 <  if (remove_xline_match(gecos))
92 <  {
93 <    sendto_one_notice(source_p, &me, ":X-Line for [%s] is removed", gecos);
94 <    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
95 <                         "%s has removed the X-Line for: [%s]",
96 <                         get_oper_name(source_p), gecos);
97 <    ilog(LOG_TYPE_XLINE, "%s removed X-Line for [%s]",
98 <         get_oper_name(source_p), gecos);
99 <  }
100 <  else
101 <    sendto_one_notice(source_p, &me, ":No X-Line for %s", gecos);
102 < }
103 <
104 < /* valid_xline()
105 < *
106 < * inputs       - client to complain to, gecos, reason, whether to complain
107 < * outputs      - 1 for valid, else 0
108 < * side effects - complains to client, when warn != 0
109 < */
110 < static int
111 < valid_xline(struct Client *source_p, const char *gecos, const char *reason, int warn)
112 < {
113 <  if (EmptyString(reason))
85 >  struct GecosItem *gecos;
86 >  if ((gecos = gecos_find(aline->host, match)))
87    {
88 <    if (warn)
89 <      sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "XLINE");
90 <    return 0;
91 <  }
119 <
120 <  if (!valid_wild_card_simple(gecos))
121 <  {
122 <    if (warn)
123 <      sendto_one_notice(source_p, &me, ":Please include at least %d non-wildcard characters with the xline",
124 <                        ConfigFileEntry.min_nonwildcard_simple);
125 <
126 <    return 0;
88 >    if (IsClient(source_p))
89 >      sendto_one_notice(source_p, &me, ":[%s] already X-Lined by [%s] - %s",
90 >                        aline->host, gecos->mask, gecos->reason);
91 >    return;
92    }
93  
94 <  return 1;
95 < }
96 <
97 < /* write_xline()
98 < *
134 < * inputs       - client taking credit for xline, gecos, reason, xline type
135 < * outputs      - none
136 < * side effects - when successful, adds an xline to the conf
137 < */
138 < static void
139 < write_xline(struct Client *source_p, char *gecos, char *reason,
140 <            time_t tkline_time)
141 < {
142 <  struct MaskItem *conf = conf_make(CONF_XLINE);
143 <
144 <  collapse(gecos);
145 <  conf->name = xstrdup(gecos);
146 <  conf->reason = xstrdup(reason);
147 <  conf->setat = CurrentTime;
148 <
149 <  SetConfDatabase(conf);
94 >  if (aline->duration)
95 >    snprintf(buf, sizeof(buf), "Temporary X-line %ju min. - %.*s (%s)",
96 >             aline->duration / 60, REASONLEN, aline->reason, date_iso8601(0));
97 >  else
98 >    snprintf(buf, sizeof(buf), "%.*s (%s)", REASONLEN, aline->reason, date_iso8601(0));
99  
100 <  if (tkline_time != 0)
101 <  {
102 <    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
103 <                         "%s added temporary %d min. X-Line for [%s] [%s]",
104 <                         get_oper_name(source_p), (int)tkline_time/60,
105 <                         conf->name, conf->reason);
106 <    sendto_one_notice(source_p, &me, ":Added temporary %d min. X-Line [%s]",
107 <                      (int)tkline_time/60, conf->name);
108 <    ilog(LOG_TYPE_XLINE, "%s added temporary %d min. X-Line for [%s] [%s]",
109 <         source_p->name, (int)tkline_time/60, conf->name, conf->reason);
110 <    conf->until = CurrentTime + tkline_time;
100 >  gecos = gecos_make();
101 >  gecos->mask = xstrdup(aline->host);
102 >  gecos->reason = xstrdup(buf);
103 >  gecos->setat = CurrentTime;
104 >  gecos->in_database = true;
105 >
106 >  if (aline->duration)
107 >  {
108 >    gecos->expire = CurrentTime + aline->duration;
109 >
110 >    if (IsClient(source_p))
111 >      sendto_one_notice(source_p, &me, ":Added temporary %ju min. X-Line [%s]",
112 >                        aline->duration / 60, gecos->mask);
113 >
114 >    sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
115 >                         "%s added temporary %ju min. X-Line for [%s] [%s]",
116 >                         get_oper_name(source_p), aline->duration / 60,
117 >                         gecos->mask, gecos->reason);
118 >    ilog(LOG_TYPE_XLINE, "%s added temporary %ju min. X-Line for [%s] [%s]",
119 >         get_oper_name(source_p), aline->duration / 60, gecos->mask, gecos->reason);
120    }
121    else
122    {
123 <    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
123 >    if (IsClient(source_p))
124 >      sendto_one_notice(source_p, &me, ":Added X-Line [%s] [%s]",
125 >                        gecos->mask, gecos->reason);
126 >
127 >    sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
128                           "%s added X-Line for [%s] [%s]",
129 <                         get_oper_name(source_p), conf->name,
130 <                         conf->reason);
169 <    sendto_one_notice(source_p, &me, ":Added X-Line [%s] [%s]",
170 <                      conf->name, conf->reason);
129 >                         get_oper_name(source_p), gecos->mask,
130 >                         gecos->reason);
131      ilog(LOG_TYPE_XLINE, "%s added X-Line for [%s] [%s]",
132 <         get_oper_name(source_p), conf->name, conf->reason);
132 >         get_oper_name(source_p), gecos->mask, gecos->reason);
133    }
134  
135 <  check_xline(conf);
176 < }
177 <
178 < static void
179 < relay_xline(struct Client *source_p, char *parv[])
180 < {
181 <  struct MaskItem *conf = NULL;
182 <  int t_sec;
183 <
184 <  t_sec = atoi(parv[3]);
185 <
186 <  sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
187 <                     "XLINE %s %s %s :%s",
188 <                     parv[1], parv[2], parv[3], parv[4]);
189 <
190 <  if (match(parv[1], me.name))
191 <    return;
192 <
193 <  if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(CONF_ULINE, source_p->servptr->name,
194 <                              source_p->username, source_p->host,
195 <                              SHARED_XLINE))
196 <  {
197 <    if ((conf = find_matching_name_conf(CONF_XLINE, parv[2], NULL, NULL, 0)))
198 <    {
199 <      sendto_one_notice(source_p, &me, ":[%s] already X-Lined by [%s] - %s",
200 <                        parv[2], conf->name, conf->reason);
201 <      return;
202 <    }
203 <
204 <    write_xline(source_p, parv[2], parv[4], t_sec);
205 <  }
135 >  xline_check(gecos);
136   }
137  
138   /* mo_xline()
# Line 218 | Line 148 | relay_xline(struct Client *source_p, cha
148   static int
149   mo_xline(struct Client *source_p, int parc, char *parv[])
150   {
151 <  char *reason = NULL;
222 <  char *gecos = NULL;
223 <  struct MaskItem *conf = NULL;
224 <  char *target_server = NULL;
225 <  time_t tkline_time = 0;
151 >  struct aline_ctx aline = { .add = true, .requires_user = false };
152  
153    if (!HasOFlag(source_p, OPER_FLAG_XLINE))
154    {
# Line 230 | Line 156 | mo_xline(struct Client *source_p, int pa
156      return 0;
157    }
158  
159 <  /*
234 <   * XLINE <gecos> <time> ON <mask> :<reason>
235 <   * XLINE <gecos> ON <mask> :<reason>
236 <   */
237 <  if (parse_aline("XLINE", source_p, parc, parv, AWILD, &gecos, NULL,
238 <                  &tkline_time, &target_server, &reason) < 0)
159 >  if (parse_aline("XLINE", source_p, parc, parv, &aline) == false)
160      return 0;
161  
162 <  if (target_server != NULL)
162 >  if (aline.server)
163    {
164 <    /* if a given expire time is given, ENCAP it */
165 <    if (tkline_time != 0)
245 <      sendto_match_servs(source_p, target_server, CAP_ENCAP,
246 <                         "ENCAP %s XLINE %d %s 0 :%s",
247 <                         target_server, (int)tkline_time, gecos, reason);
248 <    else
249 <      sendto_match_servs(source_p, target_server, CAP_CLUSTER,
250 <                         "XLINE %s %s %d :%s",
251 <                         target_server, gecos, (int)tkline_time, reason);
164 >    sendto_match_servs(source_p, aline.server, CAPAB_CLUSTER, "XLINE %s %s %ju :%s",
165 >                       aline.server, aline.host, aline.duration, aline.reason);
166  
167      /* Allow ON to apply local xline as well if it matches */
168 <    if (match(target_server, me.name))
168 >    if (match(aline.server, me.name))
169        return 0;
170    }
171    else
172 <  {
173 <    if (tkline_time != 0)
260 <      cluster_a_line(source_p, "ENCAP", CAP_ENCAP, SHARED_XLINE,
261 <                     "XLINE %d %s 0 :%s", (int)tkline_time, gecos, reason);
262 <    else
263 <      cluster_a_line(source_p, "XLINE", CAP_KLN, SHARED_XLINE,
264 <                     "%s 0 :%s", gecos, reason);
265 <  }
266 <
267 <  if (!valid_xline(source_p, gecos, reason, 0))
268 <    return 0;
172 >    cluster_distribute(source_p, "XLINE", CAPAB_CLUSTER, CLUSTER_XLINE, "%s %ju :%s",
173 >                       aline.host, aline.duration, aline.reason);
174  
175 <  if ((conf = find_matching_name_conf(CONF_XLINE, gecos, NULL, NULL, 0)))
271 <  {
272 <    sendto_one_notice(source_p, &me, ":[%s] already X-Lined by [%s] - %s",
273 <                      gecos, conf->name, conf->reason);
274 <    return 0;
275 <  }
276 <
277 <  write_xline(source_p, gecos, reason, tkline_time);
175 >  xline_handle(source_p, &aline);
176    return 0;
177   }
178  
179 < /* ms_xline()
282 < *
283 < * inputs       - oper, target server, xline, {type}, reason
179 > /*! \brief XLINE command handler
180   *
181 < * outputs      - none
182 < * side effects - propagates xline, applies it if we are a target
181 > * \param source_p Pointer to allocated Client struct from which the message
182 > *                 originally comes from.  This can be a local or remote client.
183 > * \param parc     Integer holding the number of supplied arguments.
184 > * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
185 > *                 pointers.
186 > * \note Valid arguments for this command are:
187 > *      - parv[0] = command
188 > *      - parv[1] = target server mask
189 > *      - parv[2] = gecos
190 > *      - parv[3] = duration in seconds
191 > *      - parv[4] = reason
192   */
193   static int
194   ms_xline(struct Client *source_p, int parc, char *parv[])
195   {
196 <  if (parc != 5 || EmptyString(parv[4]))
292 <    return 0;
293 <
294 <  if (!IsClient(source_p))
295 <    return 0;
296 <
297 <  if (!valid_xline(source_p, parv[2], parv[4], 0))
298 <    return 0;
299 <
300 <  relay_xline(source_p, parv);
301 <  return 0;
302 < }
303 <
304 < /* me_xline()
305 < *
306 < * inputs       - server
307 < *              - client (oper)
308 < *              - parc number of arguments
309 < *              - parv list of arguments
310 < * via parv[]
311 < * parv[1] = target server
312 < * parv[2] = xline
313 < * parv[3] = time
314 < * parv[4] = reason
315 < *
316 < * outputs      - none
317 < * side effects -
318 < */
319 < static int
320 < me_xline(struct Client *source_p, int parc, char *parv[])
321 < {
322 <  if (!IsClient(source_p) || parc != 5)
323 <    return 0;
324 <
325 <  relay_xline(source_p, parv);
326 <  return 0;
327 < }
328 <
329 < /* mo_unxline()
330 < *
331 < * inputs       - pointer to server
332 < *              - pointer to client
333 < *              - parameter count
334 < *              - parameter list
335 < * output       -
336 < * side effects - removes a xline
337 < */
338 < static int
339 < mo_unxline(struct Client *source_p, int parc, char *parv[])
340 < {
341 <  char *gecos = NULL;
342 <  char *target_server = NULL;
343 <
344 <  if (!HasOFlag(source_p, OPER_FLAG_UNXLINE))
196 >  struct aline_ctx aline =
197    {
198 <    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "unxline");
199 <    return 0;
200 <  }
198 >    .add = true,
199 >    .requires_user = false,
200 >    .host = parv[2],
201 >    .reason = parv[4],
202 >    .server = parv[1],
203 >    .duration = strtoumax(parv[3], NULL, 10)
204 >  };
205  
206 <  /* UNXLINE bill ON irc.server.com */
351 <  if (parse_aline("UNXLINE", source_p, parc, parv, 0, &gecos,
352 <                  NULL, NULL, &target_server, NULL) < 0)
206 >  if (parc != 5 || EmptyString(parv[parc - 1]))
207      return 0;
208  
209 <  if (target_server != NULL)
210 <  {
357 <    sendto_match_servs(source_p, target_server, CAP_CLUSTER,
358 <                       "UNXLINE %s %s", target_server, gecos);
359 <
360 <    /* Allow ON to apply local unxline as well if it matches */
361 <    if (match(target_server, me.name))
362 <      return 0;
363 <  }
364 <  else
365 <    cluster_a_line(source_p, "UNXLINE", CAP_CLUSTER, SHARED_UNXLINE,
366 <                   "%s", gecos);
367 <
368 <  remove_xline(source_p, gecos);
369 <  return 0;
370 < }
209 >  sendto_match_servs(source_p, aline.server, CAPAB_CLUSTER, "XLINE %s %s %ju :%s",
210 >                     aline.server, aline.host, aline.duration, aline.reason);
211  
212 < /* ms_unxline()
373 < *
374 < * inputs       - oper, target server, gecos
375 < * outputs      - none
376 < * side effects - propagates unxline, applies it if we are a target
377 < */
378 < static int
379 < ms_unxline(struct Client *source_p, int parc, char *parv[])
380 < {
381 <  if (parc != 3)
212 >  if (match(aline.server, me.name))
213      return 0;
214  
215 <  if (!IsClient(source_p) || EmptyString(parv[2]))
216 <    return 0;
217 <
218 <  sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
388 <                     "UNXLINE %s %s", parv[1], parv[2]);
389 <
390 <  if (match(parv[1], me.name))
391 <    return 0;
215 >  if (HasFlag(source_p, FLAGS_SERVICE) ||
216 >      shared_find(SHARED_XLINE, source_p->servptr->name,
217 >                  source_p->username, source_p->host))
218 >    xline_handle(source_p, &aline);
219  
393  if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(CONF_ULINE, source_p->servptr->name,
394                              source_p->username, source_p->host,
395                              SHARED_UNXLINE))
396    remove_xline(source_p, parv[2]);
220    return 0;
221   }
222  
223   static struct Message xline_msgtab =
224   {
225 <  "XLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
226 <  { m_unregistered, m_not_oper, ms_xline, me_xline, mo_xline, m_ignore }
227 < };
228 <
229 < static struct Message unxline_msgtab =
230 < {
231 <  "UNXLINE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
232 <  { m_unregistered, m_not_oper, ms_unxline, m_ignore, mo_unxline, m_ignore }
225 >  .cmd = "XLINE",
226 >  .args_min = 2,
227 >  .args_max = MAXPARA,
228 >  .handlers[UNREGISTERED_HANDLER] = m_unregistered,
229 >  .handlers[CLIENT_HANDLER] = m_not_oper,
230 >  .handlers[SERVER_HANDLER] = ms_xline,
231 >  .handlers[ENCAP_HANDLER] = m_ignore,
232 >  .handlers[OPER_HANDLER] = mo_xline
233   };
234  
235   static void
236   module_init(void)
237   {
238    mod_add_cmd(&xline_msgtab);
416  mod_add_cmd(&unxline_msgtab);
239   }
240  
241   static void
242   module_exit(void)
243   {
244    mod_del_cmd(&xline_msgtab);
423  mod_del_cmd(&unxline_msgtab);
245   }
246  
247   struct module module_entry =
248   {
428  .node    = { NULL, NULL, NULL },
429  .name    = NULL,
249    .version = "$Revision$",
431  .handle  = NULL,
250    .modinit = module_init,
251    .modexit = module_exit,
434  .flags   = 0
252   };

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)