Exemplo n.º 1
0
/*! \brief REHASH command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = option [CONF, DNS, MOTD]
 * or for remote REHASH:
 *      - parv[0] = command
 *      - parv[1] = target server mask
 *      - parv[2] = option [CONF, DNS, MOTD]
 */
static int
mo_rehash(struct Client *source_p, int parc, char *parv[])
{
  const char *option = NULL;
  const char *server = NULL;

  if (EmptyString(parv[parc - 1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "REHASH");
    return 0;
  }

  if (parc < 3)
  {
    if (!HasOFlag(source_p, OPER_FLAG_REHASH))
    {
      sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "rehash");
      return 0;
    }

    option = parv[1];
  }
  else
  {
    if (!HasOFlag(source_p, OPER_FLAG_REHASH_REMOTE))
    {
      sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "rehash:remote");
      return 0;
    }

    server = parv[1];
    option = parv[2];
  }

  for (const struct RehashStruct *tab = rehash_cmd_table; tab->handler; ++tab)
  {
    if (irccmp(tab->option, option))
      continue;

    if (!EmptyString(server))
      sendto_match_servs(source_p, server, 0, "REHASH %s %s", server, option);

    if (EmptyString(server) || match(server, me.name))
      tab->handler(source_p);

    return 0;
  }

  sendto_one_notice(source_p, &me, ":%s is not a valid option. "
                    "Choose from CONF, DNS, MOTD",
                    option);
  return 0;
}
Exemplo n.º 2
0
/*! \brief RESTART command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = server name
 */
static int
mo_restart(struct Client *source_p, int parc, char *parv[])
{
  char buf[IRCD_BUFSIZE] = "";
  const char *const name = parv[1];

  if (!HasOFlag(source_p, OPER_FLAG_RESTART))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "restart");
    return 0;
  }

  if (EmptyString(name))
  {
    sendto_one_notice(source_p, &me, ":Need server name /restart %s", me.name);
    return 0;
  }

  if (irccmp(name, me.name))
  {
    sendto_one_notice(source_p, &me, ":Mismatch on /restart %s", me.name);
    return 0;
  }

  snprintf(buf, sizeof(buf), "received RESTART command from %s",
           get_client_name(source_p, HIDE_IP));
  server_die(buf, 1);
  return 0;
}
Exemplo n.º 3
0
/*! \brief UNRESV command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = channel/nick
 *      - parv[2] = "ON"
 *      - parv[3] = target server
 */
static int
mo_unresv(struct Client *source_p, int parc, char *parv[])
{
  char *resv = NULL;
  char *reason = NULL;
  char *target_server = NULL;

  if (!HasOFlag(source_p, OPER_FLAG_UNRESV))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "unresv");
    return 0;
  }

  if (!parse_aline("UNRESV", source_p, parc, parv, 0, &resv, NULL,
                   NULL, &target_server, &reason))
    return 0;

  if (target_server)
  {
    sendto_match_servs(source_p, target_server, CAPAB_CLUSTER, "UNRESV %s %s",
                       target_server, resv);

    /* Allow ON to apply local unresv as well if it matches */
    if (match(target_server, me.name))
      return 0;
  }
  else
    cluster_a_line(source_p, "UNRESV", CAPAB_KLN, SHARED_UNRESV, resv);

  resv_remove(source_p, resv);
  return 0;
}
Exemplo n.º 4
0
/*! \brief DIE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = server name
 */
static int
mo_die(struct Client *source_p, int parc, char *parv[])
{
  char buf[IRCD_BUFSIZE] = "";

  if (!HasOFlag(source_p, OPER_FLAG_DIE))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "die");
    return 0;
  }

  if (parc < 2 || EmptyString(parv[1]))
  {
    sendto_one_notice(source_p, &me, ":Need server name /die %s", me.name);
    return 0;
  }

  if (irccmp(parv[1], me.name))
  {
    sendto_one_notice(source_p, &me, ":Mismatch on /die %s", me.name);
    return 0;
  }

  snprintf(buf, sizeof(buf), "received DIE command from %s",
           get_client_name(source_p, HIDE_IP));
  server_die(buf, 0);
  return 0;
}
Exemplo n.º 5
0
/*
 * mo_wallops (write to *all* opers currently online)
 *      parv[0] = sender prefix
 *      parv[1] = message text
 */
static void
mo_wallops(struct Client *client_p, struct Client *source_p,
           int parc, char *parv[])
{
    const char *message = parv[1];

    if (!HasOFlag(source_p, OPER_FLAG_WALLOPS))
    {
        sendto_one(source_p, form_str(ERR_NOPRIVS),
                   me.name, source_p->name, "wallops");
        return;
    }

    if (EmptyString(message))
    {
        sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
                   me.name, source_p->name, "WALLOPS");
        return;
    }

    sendto_wallops_flags(UMODE_OPERWALL, source_p, "OPERWALL - %s", message);
    sendto_server(NULL, CAP_TS6, NOCAPS,
                  ":%s WALLOPS :%s", ID(source_p), message);
    sendto_server(NULL, NOCAPS, CAP_TS6,
                  ":%s WALLOPS :%s", source_p->name, message);
}
Exemplo n.º 6
0
/*
** m_undline
** added May 28th 2000 by Toby Verrall <*****@*****.**>
** based totally on m_unkline
** added to hybrid-7 7/11/2000 --is
**
**      parv[0] = sender nick
**      parv[1] = dline to remove
*/
static void
mo_undline(struct Client *client_p, struct Client *source_p,
           int parc, char *parv[])
{
  char *addr = NULL, *user = NULL;
  char *target_server = NULL;

  if (!HasOFlag(source_p, OPER_FLAG_UNDLINE))
  {
    sendto_one(source_p, form_str(ERR_NOPRIVS),
               me.name, source_p->name, "undline");
    return;
  }

  if (parc < 2 || EmptyString(parv[1]))
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               me.name, source_p->name, "UNDLINE");
    return;
  }

  if (parse_aline("UNDLINE", source_p, parc, parv, 0, &user,
                  &addr, NULL, &target_server, NULL) < 0)
    return;

  if (target_server != NULL)
  {
    sendto_match_servs(source_p, target_server, CAP_UNDLN,
                       "UNDLINE %s %s", target_server, addr);

    /* Allow ON to apply local unkline as well if it matches */
    if (match(target_server, me.name))
      return;
  }
  else
    cluster_a_line(source_p, "UNDLINE", CAP_UNDLN, SHARED_UNDLINE,
                   "%s", addr);

  if (remove_dline_match(addr))
  {
    sendto_one(source_p,
               ":%s NOTICE %s :D-Line for [%s] is removed",
               me.name, source_p->name, addr);
    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
                         "%s has removed the D-Line for: [%s]",
                         get_oper_name(source_p), addr);
    ilog(LOG_TYPE_DLINE, "%s removed D-Line for [%s]",
         get_oper_name(source_p), addr);
  }
  else
    sendto_one(source_p, ":%s NOTICE %s :No D-Line for [%s] found",
               me.name, source_p->name, addr);
}
Exemplo n.º 7
0
/*! \brief REHASH command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = additional option
 */
static int
mo_rehash(struct Client *source_p, int parc, char *parv[])
{
  int found = 0;
  const char *const option = parv[1];

  if (!HasOFlag(source_p, OPER_FLAG_REHASH))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "rehash");
    return 0;
  }

  if (!EmptyString(option))
  {
    if (!irccmp(option, "DNS"))
    {
      sendto_one_numeric(source_p, &me, RPL_REHASHING, "DNS");
      sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
                           "%s is rehashing DNS",
                           get_oper_name(source_p));
      restart_resolver();
      found = 1;
    }
    else if (!irccmp(option, "MOTD"))
    {
      sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
                           "%s is forcing re-reading of MOTD files",
                           get_oper_name(source_p));
      motd_recache();
      found = 1;
    }

    if (found)
      ilog(LOG_TYPE_IRCD, "REHASH %s From %s",
           option, get_oper_name(source_p));
    else
      sendto_one_notice(source_p, &me, ":%s is not a valid option. "
                        "Choose from DNS, MOTD", option);
  }
  else
  {
    sendto_one_numeric(source_p, &me, RPL_REHASHING, ConfigGeneral.configfile);
    sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
                         "%s is rehashing configuration file(s)",
                         get_oper_name(source_p));
    ilog(LOG_TYPE_IRCD, "REHASH From %s",
         get_oper_name(source_p));
    conf_rehash(0);
  }

  return 0;
}
Exemplo n.º 8
0
/*! \brief UNKLINE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = user\@host mask
 *      - parv[2] = "ON"
 *      - parv[3] = target server
 */
static int
mo_unkline(struct Client *source_p, int parc, char *parv[])
{
  char *target_server = NULL;
  char *user, *host;

  if (!HasOFlag(source_p, OPER_FLAG_UNKLINE))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "unkline");
    return 0;
  }

  if (EmptyString(parv[1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "UNKLINE");
    return 0;
  }

  if (parse_aline("UNKLINE", source_p, parc, parv, 0, &user,
                  &host, NULL, &target_server, NULL) < 0)
    return 0;

  if (target_server)
  {
     sendto_match_servs(source_p, target_server, CAP_UNKLN,
                        "UNKLINE %s %s %s",
                        target_server, user, host);

    /* Allow ON to apply local unkline as well if it matches */
    if (match(target_server, me.name))
      return 0;
  }
  else
    cluster_a_line(source_p, "UNKLINE", CAP_UNKLN, SHARED_UNKLINE,
                   "%s %s", user, host);

  if (remove_kline_match(host, user))
  {
    sendto_one_notice(source_p, &me, ":K-Line for [%s@%s] is removed", user, host);
    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
                         "%s has removed the K-Line for: [%s@%s]",
                         get_oper_name(source_p), user, host);
    ilog(LOG_TYPE_KLINE, "%s removed K-Line for [%s@%s]",
         get_oper_name(source_p), user, host);
  }
  else
    sendto_one_notice(source_p, &me, ":No K-Line for [%s@%s] found", user, host);
  return 0;
}
Exemplo n.º 9
0
/*! \brief Blindly opers up given source_p, using conf info.
 *         All checks on passwords have already been done.
 * \param source_p Pointer to given client to oper
 * \param conf operator {} configuration record
 */
static void
oper_up(struct Client *source_p, const struct MaskItem *conf)
{
  const unsigned int old = source_p->umodes;

  ++Count.oper;
  SetOper(source_p);

  if (conf->modes)
    AddUMode(source_p, conf->modes);
  else if (ConfigGeneral.oper_umodes)
    AddUMode(source_p, ConfigGeneral.oper_umodes);

  if (!(old & UMODE_INVISIBLE) && HasUMode(source_p, UMODE_INVISIBLE))
    ++Count.invisi;
  else if ((old & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
    --Count.invisi;

  assert(dlinkFind(&oper_list, source_p) == NULL);
  dlinkAdd(source_p, make_dlink_node(), &oper_list);

  AddOFlag(source_p, conf->port);

  if (HasOFlag(source_p, OPER_FLAG_ADMIN))
    AddUMode(source_p, UMODE_ADMIN);

  if (!EmptyString(conf->whois))
  {
    svstag_attach(&source_p->svstags, RPL_WHOISOPERATOR, "+", conf->whois);
    sendto_server(NULL, 0, 0, ":%s SVSTAG %s %ju %u + :%s",
                  me.id, source_p->id, source_p->tsinfo,
                  RPL_WHOISOPERATOR, conf->whois);
  }

  ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s", conf->name, source_p->name,
       source_p->username, source_p->host);
  sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE, "%s is now an operator",
                       get_oper_name(source_p));
  sendto_server(NULL, 0, 0, ":%s GLOBOPS :%s is now an operator",
                me.id, get_oper_name(source_p));

  send_umode_out(source_p, old);
  sendto_one_numeric(source_p, &me, RPL_YOUREOPER);
}
Exemplo n.º 10
0
/*! \brief LOCOPS command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = message text
 */
static int
mo_locops(struct Client *source_p, int parc, char *parv[])
{
  const char *const message = parv[1];

  if (!HasOFlag(source_p, OPER_FLAG_LOCOPS))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "locops");
    return 0;
  }

  if (EmptyString(message))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "LOCOPS");
    return 0;
  }

  sendto_realops_flags(UMODE_LOCOPS, L_ALL, SEND_LOCOPS, "from %s: %s",
                       source_p->name, message);
  cluster_distribute(source_p, "LOCOPS", 0, CLUSTER_LOCOPS, message);
  return 0;
}
Exemplo n.º 11
0
/*! \brief WALLOPS command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = message text
 */
static int
mo_wallops(struct Client *source_p, int parc, char *parv[])
{
  const char *const message = parv[1];

  if (!HasOFlag(source_p, OPER_FLAG_WALLOPS))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "wallops");
    return 0;
  }

  if (EmptyString(message))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "WALLOPS");
    return 0;
  }

  sendto_wallops_flags(UMODE_WALLOP, source_p, "%s", message);
  sendto_server(source_p, 0, 0, ":%s WALLOPS :%s",
                source_p->id, message);
  return 0;
}
Exemplo n.º 12
0
/*! \brief GLOBOPS command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = message text
 */
static int
mo_globops(struct Client *source_p, int parc, char *parv[])
{
  const char *const message = parv[1];

  if (!HasOFlag(source_p, OPER_FLAG_GLOBOPS))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "globops");
    return 0;
  }

  if (EmptyString(message))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "GLOBOPS");
    return 0;
  }

  sendto_server(source_p, 0, 0, ":%s GLOBOPS :%s",
                source_p->id, message);
  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_GLOBAL, "from %s: %s",
                       source_p->name, message);
  return 0;
}
Exemplo n.º 13
0
/* set_user_mode()
 *
 * added 15/10/91 By Darren Reed.
 * parv[0] - command
 * parv[1] - username to change mode for
 * parv[2] - modes to change
 */
static void
set_user_mode(struct Client *source_p, const int parc, char *parv[])
{
  const struct user_modes *tab = NULL;
  const unsigned int setmodes = source_p->umodes;
  const struct Client *target_p = NULL;
  int what = MODE_ADD, badmode = 0;

  if ((target_p = find_person(source_p, parv[1])) == NULL)
  {
    if (MyConnect(source_p))
      sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
    return;
  }

  if (source_p != target_p)
  {
     sendto_one_numeric(source_p, &me, ERR_USERSDONTMATCH);
     return;
  }

  if (parc < 3)
  {
    char buf[IRCD_BUFSIZE] = "";
    char *m = buf;

    *m++ = '+';
    for (tab = umode_tab; tab->c; ++tab)
      if (HasUMode(source_p, tab->flag))
        *m++ = tab->c;
    *m = '\0';

    sendto_one_numeric(source_p, &me, RPL_UMODEIS, buf);
    return;
  }

  /* Parse user mode change string */
  for (const char *m = parv[2]; *m; ++m)
  {
    switch (*m)
    {
      case '+':
        what = MODE_ADD;
        break;
      case '-':
        what = MODE_DEL;
        break;
      case 'o':
        if (what == MODE_ADD)
        {
          if (!MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER))
          {
            ++Count.oper;
            SetOper(source_p);
          }
        }
        else
        {
          if (!HasUMode(source_p, UMODE_OPER))
            break;

          ClearOper(source_p);
          --Count.oper;

          if (MyConnect(source_p))
          {
            dlink_node *node = NULL;

            detach_conf(source_p, CONF_OPER);
            ClrOFlag(source_p);
            DelUMode(source_p, ConfigGeneral.oper_only_umodes);

            if ((node = dlinkFindDelete(&oper_list, source_p)))
              free_dlink_node(node);
          }
        }

        break;

      case 'S':  /* Only servers may set +S in a burst */
      case 'W':  /* Only servers may set +W in a burst */
      case 'r':  /* Only services may set +r */
      case 'x':  /* Only services may set +x */
        break;

      default:
        if ((tab = umode_map[(unsigned char)*m]))
        {
          if (MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER) &&
              (ConfigGeneral.oper_only_umodes & tab->flag))
            badmode = 1;
          else
          {
            if (what == MODE_ADD)
              AddUMode(source_p, tab->flag);
            else
              DelUMode(source_p, tab->flag);
          }
        }
        else if (MyConnect(source_p))
          badmode = 1;

        break;
    }
  }

  if (badmode)
    sendto_one_numeric(source_p, &me, ERR_UMODEUNKNOWNFLAG);

  if (MyConnect(source_p) && HasUMode(source_p, UMODE_ADMIN) &&
      !HasOFlag(source_p, OPER_FLAG_ADMIN))
  {
    sendto_one_notice(source_p, &me, ":*** You have no admin flag;");
    DelUMode(source_p, UMODE_ADMIN);
  }

  if (!(setmodes & UMODE_INVISIBLE) && HasUMode(source_p, UMODE_INVISIBLE))
    ++Count.invisi;
  if ((setmodes & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
    --Count.invisi;

  /*
   * Compare new modes with old modes and send string which will cause
   * servers to update correctly.
   */
  send_umode_out(source_p, setmodes);
}
Exemplo n.º 14
0
/*! \brief UNXLINE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = gecos
 *      - parv[2] = "ON"
 *      - parv[3] = target server
 */
static int
mo_unxline(struct Client *source_p, int parc, char *parv[])
{
  struct aline_ctx aline = { .add = false, .simple_mask = true };

  if (!HasOFlag(source_p, OPER_FLAG_UNXLINE))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "unxline");
    return 0;
  }

  if (parse_aline("UNXLINE", source_p, parc, parv, &aline) == false)
    return 0;

  if (aline.server)
  {
    sendto_match_servs(source_p, aline.server, CAPAB_CLUSTER, "UNXLINE %s %s",
                       aline.server, aline.mask);

    /* Allow ON to apply local unxline as well if it matches */
    if (match(aline.server, me.name))
      return 0;
  }
  else
    cluster_distribute(source_p, "UNXLINE", CAPAB_CLUSTER, CLUSTER_UNXLINE, "%s", aline.host);

  xline_remove(source_p, &aline);
  return 0;
}

/*! \brief UNXLINE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = target server mask
 *      - parv[2] = gecos
 */
static int
ms_unxline(struct Client *source_p, int parc, char *parv[])
{
  struct aline_ctx aline =
  {
    .add = false,
    .simple_mask = true,
    .mask = parv[2],
    .server = parv[1]
  };

  if (parc != 3 || EmptyString(parv[parc - 1]))
    return 0;

  sendto_match_servs(source_p, aline.server, CAPAB_CLUSTER, "UNXLINE %s %s",
                     aline.server, aline.mask);

  if (match(aline.server, me.name))
    return 0;

  if (HasFlag(source_p, FLAGS_SERVICE) ||
      shared_find(SHARED_UNXLINE, source_p->servptr->name,
                  source_p->username, source_p->host))
    xline_remove(source_p, &aline);
  return 0;
}

static struct Message unxline_msgtab =
{
  .cmd = "UNXLINE",
  .args_min = 2,
  .args_max = MAXPARA,
  .handlers[UNREGISTERED_HANDLER] = m_unregistered,
  .handlers[CLIENT_HANDLER] = m_not_oper,
  .handlers[SERVER_HANDLER] = ms_unxline,
  .handlers[ENCAP_HANDLER] = m_ignore,
  .handlers[OPER_HANDLER] = mo_unxline
};

static void
module_init(void)
{
  mod_add_cmd(&unxline_msgtab);
}

static void
module_exit(void)
{
  mod_del_cmd(&unxline_msgtab);
}

struct module module_entry =
{
  .version = "$Revision$",
  .modinit = module_init,
  .modexit = module_exit,
};
Exemplo n.º 15
0
/* mo_dline()
 *
 * inputs	- pointer to server
 *		- pointer to client
 *		- parameter count
 *		- parameter list
 * output	-
 * side effects - D line is added
 *
 */
static void
mo_dline(struct Client *client_p, struct Client *source_p,
         int parc, char *parv[])
{
  char def_reason[] = CONF_NOREASON;
  char *dlhost = NULL, *reason = NULL;
  char *target_server = NULL;
  const char *creason;
  const struct Client *target_p = NULL;
  struct irc_ssaddr daddr;
  struct MaskItem *conf=NULL;
  time_t tkline_time=0;
  int bits = 0, aftype = 0, t = 0;
  const char *current_date = NULL;
  time_t cur_time;
  char hostip[HOSTIPLEN + 1];
  char buffer[IRCD_BUFSIZE];

  if (!HasOFlag(source_p, OPER_FLAG_DLINE))
  {
    sendto_one(source_p, form_str(ERR_NOPRIVS),
               me.name, source_p->name, "dline");
    return;
  }

  if (parse_aline("DLINE", source_p,  parc, parv, AWILD, &dlhost,
                  NULL, &tkline_time, &target_server, &reason) < 0)
    return;

  if (target_server != NULL)
  {
    if (HasID(source_p))
    {
      sendto_server(NULL, CAP_DLN|CAP_TS6, NOCAPS,
                    ":%s DLINE %s %lu %s :%s",
                    source_p->id, target_server, (unsigned long)tkline_time,
                    dlhost, reason);
      sendto_server(NULL, CAP_DLN, CAP_TS6,
                    ":%s DLINE %s %lu %s :%s",
                    source_p->name, target_server, (unsigned long)tkline_time,
                    dlhost, reason);
    }
    else
      sendto_server(NULL, CAP_DLN, NOCAPS,
                    ":%s DLINE %s %lu %s :%s",
                    source_p->name, target_server, (unsigned long)tkline_time,
                    dlhost, reason);

    /* Allow ON to apply local kline as well if it matches */
    if (match(target_server, me.name))
      return;
  }
  else
    cluster_a_line(source_p, "DLINE", CAP_DLN, SHARED_DLINE,
                   "%d %s :%s", tkline_time, dlhost, reason);

  if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST)
  {
    if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL)
      return;

    if (!MyConnect(target_p))
    {
      sendto_one(source_p,
                 ":%s NOTICE %s :Can't DLINE nick on another server",
                 me.name, source_p->name);
      return;
    }

    if (IsExemptKline(target_p))
    {
      sendto_one(source_p,
                 ":%s NOTICE %s :%s is E-lined", me.name,
                 source_p->name, target_p->name);
      return;
    }

    getnameinfo((struct sockaddr *)&target_p->localClient->ip,
                target_p->localClient->ip.ss_len, hostip,
                sizeof(hostip), NULL, 0, NI_NUMERICHOST);
    dlhost = hostip;
    t = parse_netmask(dlhost, NULL, &bits);
    assert(t == HM_IPV4 || t == HM_IPV6);
  }

  if (bits < 8)
  {
    sendto_one(source_p,
               ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.",
               me.name, source_p->name);
    return;
  }

#ifdef IPV6
  if (t == HM_IPV6)
    aftype = AF_INET6;
  else
#endif
    aftype = AF_INET;

  parse_netmask(dlhost, &daddr, NULL);

  if ((conf = find_dline_conf(&daddr, aftype)) != NULL)
  {
    creason = conf->reason ? conf->reason : def_reason;
    if (IsConfExemptKline(conf))
      sendto_one(source_p,
		 ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
		 me.name, source_p->name, dlhost, conf->host, creason);
    else
      sendto_one(source_p,
		 ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
		 me.name, source_p->name, dlhost, conf->host, creason);
    return;
  }

  cur_time = CurrentTime;
  current_date = smalldate(cur_time);

  if (!valid_comment(source_p, reason, 1))
    return;

  conf = conf_make(CONF_DLINE);
  conf->host = xstrdup(dlhost);

  if (tkline_time != 0)
    snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)",
             (int)(tkline_time/60), reason, current_date);
  else
    snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);

  conf->reason = xstrdup(buffer);
  apply_dline(source_p, conf, tkline_time);
  rehashed_klines = 1;
}
Exemplo n.º 16
0
/*
 * mo_set - SET command handler
 * set options while running
 */
static int
mo_set(struct Client *source_p, int parc, char *parv[])
{
  int n;
  int newval;
  const char *strarg = NULL;
  const char *intarg = NULL;

  if (!HasOFlag(source_p, OPER_FLAG_SET))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "set");
    return 0;
  }

  if (parc > 1)
  {
    /*
     * Go through all the commands in set_cmd_table, until one is
     * matched.
     */
    for (const struct SetStruct *tab = set_cmd_table; tab->handler; ++tab)
    {
      if (irccmp(tab->name, parv[1]))
        continue;

      /*
       * Command found; now execute the code
       */
      n = 2;

      if (tab->wants_char)
        strarg = parv[n++];

      if (tab->wants_int)
        intarg = parv[n++];

      if ((n - 1) > parc)
        sendto_one_notice(source_p, &me, ":SET %s expects (\"%s%s\") args", tab->name,
                          (tab->wants_char ? "string, " : ""),
                          (tab->wants_int ? "int" : ""));

      if (parc <= 2)
      {
        strarg = NULL;
        intarg = NULL;
      }

      if (tab->wants_int && parc > 2)
      {
        if (intarg)
        {
          if (!irccmp(intarg, "yes") || !irccmp(intarg, "on"))
            newval = 1;
          else if (!irccmp(intarg, "no") || !irccmp(intarg, "off"))
            newval = 0;
          else
            newval = atoi(intarg);
        }
        else
          newval = -1;

        if (newval < 0)
        {
          sendto_one_notice(source_p, &me, ":Value less than 0 illegal for %s",
                            tab->name);
          return 0;
        }
      }
      else
        newval = -1;

      tab->handler(source_p, strarg, newval);
      return 0;
    }

    /*
     * Code here will be executed when a /QUOTE SET command is not
     * found within set_cmd_table.
     */
    sendto_one_notice(source_p, &me, ":Variable not found.");
    return 0;
  }

  list_quote_commands(source_p);
  return 0;
}
Exemplo n.º 17
0
/*! \brief CONNECT command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = target server
 *      - parv[2] = port number
 *      - parv[3] = nickname/servername
 */
static int
mo_connect(struct Client *source_p, int parc, char *parv[])
{
  int port = 0, tmpport = 0;
  struct MaskItem *conf = NULL;
  const struct Client *target_p = NULL;

  if (EmptyString(parv[1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "CONNECT");
    return 0;
  }

  if (parc > 3)
  {
    if (!HasOFlag(source_p, OPER_FLAG_CONNECT_REMOTE))
    {
      sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "connect:remote");
      return 0;
    }

    if (hunt_server(source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
      return 0;
  }
  else if (!HasOFlag(source_p, OPER_FLAG_CONNECT))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "connect");
    return 0;
  }

  /*
   * Try to find the name, then host, if both fail notify ops and bail
   */
  if (!(conf = find_matching_name_conf(CONF_SERVER, parv[1], NULL, NULL, 0)) &&
      !(conf = find_matching_name_conf(CONF_SERVER, NULL, NULL, parv[1], 0)))
  {
    sendto_one_notice(source_p, &me, ":Connect: Host %s not listed in configuration file", parv[1]);
    return 0;
  }

  if ((target_p = hash_find_server(conf->name)))
  {
    sendto_one_notice(source_p, &me, ":Connect: Server %s already exists from %s.",
                      target_p->name, target_p->from->name);
    return 0;
  }

  /*
   * Get port number from user, if given. If not specified,
   * use the default from configuration structure. If missing
   * from there, then use the precompiled default.
   */
  tmpport = port = conf->port;

  if (parc > 2 && !EmptyString(parv[2]))
  {
    if ((port = atoi(parv[2])) <= 0)
    {
      sendto_one_notice(source_p, &me, ":Connect: Illegal port number");
      return 0;
    }
  }
  else if (port <= 0 && (port = PORTNUM) <= 0)
  {
    sendto_one_notice(source_p, &me, ":Connect: missing port number");
    return 0;
  }

  if (find_servconn_in_progress(conf->name))
  {
    sendto_one_notice(source_p, &me, ":Connect: a connection to %s "
                      "is already in progress.", conf->name);
    return 0;
  }

  /*
   * Notify all operators about remote connect requests
   */
  ilog(LOG_TYPE_IRCD, "CONNECT From %s : %s %s",
       source_p->name, parv[1], parv[2] ? parv[2] : "");

  conf->port = port;

  /*
   * At this point we should be calling connect_server with a valid
   * connect{} block and a valid port in the connect{} block
   */
  if (serv_connect(conf, source_p))
  {
    if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN))
      sendto_one_notice(source_p, &me, ":*** Connecting to %s[%s].%d",
                        conf->host, conf->name, conf->port);
    else
      sendto_one_notice(source_p, &me, ":*** Connecting to %s.%d",
                        conf->name, conf->port);
  }
  else
    sendto_one_notice(source_p, &me, ":*** Couldn't connect to %s.%d",
                      conf->name, conf->port);

  /*
   * Client is either connecting with all the data it needs or has been
   * destroyed
   */
  conf->port = tmpport;
  return 0;
}
Exemplo n.º 18
0
/* mo_dline()
 *
 * inputs  - pointer to server
 *    - pointer to client
 *    - parameter count
 *    - parameter list
 * output  -
 * side effects - D line is added
 *
 */
static void
mo_dline(struct Client *client_p, struct Client *source_p,
         int parc, char *parv[])
{
  char def_reason[] = CONF_NOREASON;
  char *dlhost = NULL, *oper_reason = NULL, *reason = NULL;
  char *target_server = NULL;
  const char *creason;
  const struct Client *target_p = NULL;
  struct sockaddr_storage daddr;
  struct AccessItem *aconf = NULL;
  time_t tkline_time = 0;
  int bits, t;
  char hostip[HOSTIPLEN + 1];

  if (!HasOFlag(source_p, OPER_FLAG_DLINE))
  {
    sendto_one(source_p, form_str(ERR_NOPRIVS),
               me.name, source_p->name, "dline");
    return;
  }

  if (parse_aline("DLINE", source_p,  parc, parv, AWILD, &dlhost,
                  NULL, &tkline_time, &target_server, &reason) < 0)
    return;

  if (target_server != NULL)
  {
    if (HasID(source_p))
    {
      sendto_server(NULL, CAP_DLN | CAP_TS6, NOCAPS,
                    ":%s DLINE %s %lu %s :%s",
                    source_p->id, target_server, (unsigned long)tkline_time,
                    dlhost, reason);
      sendto_server(NULL, CAP_DLN, CAP_TS6,
                    ":%s DLINE %s %lu %s :%s",
                    source_p->name, target_server, (unsigned long)tkline_time,
                    dlhost, reason);
    }
    else
      sendto_server(NULL, CAP_DLN, NOCAPS,
                    ":%s DLINE %s %lu %s :%s",
                    source_p->name, target_server, (unsigned long)tkline_time,
                    dlhost, reason);

    /* Allow ON to apply local kline as well if it matches */
    if (!match(target_server, me.name))
      return;
  }
  else
    cluster_a_line(source_p, "DLINE", CAP_DLN, SHARED_DLINE,
                   "%d %s :%s", tkline_time, dlhost, reason);

  if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST)
  {
    if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL)
      return;

    if (!MyConnect(target_p))
    {
      sendto_one(source_p,
                 ":%s NOTICE %s :Can't DLINE nick on another server",
                 me.name, source_p->name);
      return;
    }

    if (IsExemptKline(target_p))
    {
      sendto_one(source_p,
                 ":%s NOTICE %s :%s is E-lined", me.name,
                 source_p->name, target_p->name);
      return;
    }

    ip_to_string(&target_p->ip, hostip, sizeof(hostip));
    dlhost = hostip;
    t = parse_netmask(dlhost, NULL, &bits);
    assert(t == HM_IPV4 || t == HM_IPV6);
  }

  if (bits < 8)
  {
    sendto_one(source_p,
               ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.",
               me.name, source_p->name);
    return;
  }

  if (t == HM_IPV6)
    t = AF_INET6;
  else
    t = AF_INET;

  parse_netmask(dlhost, &daddr, NULL);

  if ((aconf = find_dline_conf(&daddr, t)) != NULL)
  {
    creason = aconf->reason ? aconf->reason : def_reason;

    if (IsConfExemptKline(aconf))
      sendto_one(source_p,
                 ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
                 me.name, source_p->name, dlhost, aconf->host, creason);
    else
      sendto_one(source_p,
                 ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
                 me.name, source_p->name, dlhost, aconf->host, creason);

    return;
  }

  /* Look for an oper reason */
  if ((oper_reason = strchr(reason, '|')) != NULL)
    * oper_reason++ = '\0';

  if (!valid_comment(source_p, reason, 1))
    return;

  apply_conf_ban(source_p, DLINE_TYPE, NULL, dlhost, reason, oper_reason,
                 tkline_time);
}
Exemplo n.º 19
0
/*! \brief NICK command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = nickname
 */
static int
m_nick(struct Client *source_p, int parc, char *parv[])
{
  char nick[NICKLEN + 1] = "";
  struct Client *target_p = NULL;
  struct MaskItem *conf = NULL;

  assert(MyClient(source_p));

  if (parc < 2 || EmptyString(parv[1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NONICKNAMEGIVEN);
    return 0;
  }

  /* Mark end of grace period, to prevent nickflooding */
  if (!IsFloodDone(source_p))
    flood_endgrace(source_p);

  /* Terminate nick to NICKLEN */
  strlcpy(nick, parv[1], IRCD_MIN(sizeof(nick), ConfigServerInfo.max_nick_length + 1));

  /* Check the nickname is ok */
  if (!valid_nickname(nick, 1))
  {
    sendto_one_numeric(source_p, &me, ERR_ERRONEUSNICKNAME, nick, "Erroneous Nickname");
    return 0;
  }

  if (!HasFlag(source_p, FLAGS_EXEMPTRESV) &&
      !(HasUMode(source_p, UMODE_OPER) && HasOFlag(source_p, OPER_FLAG_NICK_RESV)) &&
      (conf = find_matching_name_conf(CONF_NRESV, nick, NULL, NULL, 0)))
  {
    ++conf->count;
    sendto_one_numeric(source_p, &me, ERR_ERRONEUSNICKNAME, nick, conf->reason);
    sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
                         "Forbidding reserved nick %s from user %s",
                         nick, get_client_name(source_p, HIDE_IP));
    return 0;
  }

  if ((target_p = hash_find_client(nick)) == NULL)
    change_local_nick(source_p, nick);
  else if (target_p == source_p)
  {
    /*
     * If (target_p == source_p) the client is changing nicks between
     * equivalent nicknames ie: [nick] -> {nick}
     */

    /* Check the nick isn't exactly the same */
    if (strcmp(target_p->name, nick))
      change_local_nick(source_p, nick);
  }
  else if (IsUnknown(target_p))
  {
    /*
     * If the client that has the nick isn't registered yet (nick but no
     * user) then drop the unregged client
     */
    exit_client(target_p, "Overridden by other sign on");
    change_local_nick(source_p, nick);
  }
  else
    sendto_one_numeric(source_p, &me, ERR_NICKNAMEINUSE, target_p->name);

  return 0;
}