Example #1
0
/*
 * m_join
 *      parv[0] = sender prefix
 *      parv[1] = channel
 *      parv[2] = channel password (key)
 */
static void
m_join(struct Client *client_p,
       struct Client *source_p,
       int parc,
       char *parv[])
{
  struct Channel *chptr = NULL;
  char  *name, *key = NULL;
  int   i, flags = 0;
  char  *p = NULL, *p2 = NULL;
  int   successful_join_count = 0; /* Number of channels successfully joined */
  
  if (*parv[1] == '\0')
    {
      sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
                 me.name, parv[0], "JOIN");
      return;
    }

  if (parc > 2)
    {
      key = strtoken(&p2, parv[2], ",");
    }

  for (name = strtoken(&p, parv[1], ","); name;
         key = (key) ? strtoken(&p2, NULL, ",") : NULL,
         name = strtoken(&p, NULL, ","))
    {

      if(!check_channel_name(name))
      {
        sendto_one(source_p, form_str(ERR_BADCHANNAME),
	           me.name, source_p->name, (unsigned char*)name);
        continue;
      }

      /*
      ** JOIN 0 sends out a part for all channels a user
      ** has joined.
      **
      ** this should be either disabled or selectable in
      ** config file .. it's abused a lot more than it's
      ** used these days :/ --is
      */
      if (*name == '0' && !atoi(name))
      {
        if (source_p->user->channel.head == NULL)
          continue;
	  
        do_join_0(&me,source_p);
	continue;
      }
      
      /* check it begins with # or & */
      else if(!IsChannelName(name))
      {
        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
	           me.name, source_p->name, name);
	continue;
      }

      if(ConfigServerHide.disable_local_channels &&
        (*name == '&'))
      {
        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
	           me.name, source_p->name, name);
        continue;
      }

      /* check the length */
      if (strlen(name) > CHANNELLEN)
      {
        sendto_one(source_p, form_str(ERR_BADCHANNAME),
	           me.name, source_p->name, name);
	continue;
      }
      
      /* see if its resv'd */
      if(find_channel_resv(name) && 
         (!IsOper(source_p) || !ConfigChannel.no_oper_resvs))
	{
	  sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
		     me.name, source_p->name, name);
          sendto_realops_flags(UMODE_SPY, L_ALL,
                   "User %s (%[email protected]%s) is attempting to join locally juped channel %s",
                   source_p->name, source_p->username, source_p->host, name);
	  continue;
	}

      /* look for the channel */
      if((chptr = hash_find_channel(name)) != NULL)
	{
	  if(IsMember(source_p, chptr))
            return;

	  if(splitmode && !IsOper(source_p) && (*name != '&') && 
             ConfigChannel.no_join_on_split)
	  {
	    sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
                       me.name, source_p->name, name);
	    continue;
	  }

	  if (chptr->users == 0)
	    flags = CHFL_CHANOP;
	  else
	    flags = 0;
	}
      else
	{
	  if(splitmode && !IsOper(source_p) && (*name != '&') && 
            (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
	  {
	    sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
	               me.name, source_p->name, name);
	    continue;
	  }
	  
	  flags = CHFL_CHANOP;
	}

      if ((source_p->user->joined >= ConfigChannel.max_chans_per_user) &&
         (!IsOper(source_p) || (source_p->user->joined >=
	                        ConfigChannel.max_chans_per_user*3)))
	{
	  sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
		     me.name, parv[0], name);
	  if(successful_join_count)
	    source_p->localClient->last_join_time = CurrentTime;
	  return;
	}

      if(flags == 0)        /* if channel doesn't exist, don't penalize */
	successful_join_count++;

      if(chptr == NULL)     /* If I already have a chptr, no point doing this */
	{
	  chptr = get_or_create_channel(source_p, name, NULL);
	}
      
      if(chptr == NULL)
	{
	  sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
		     me.name, parv[0], name);
	  if(successful_join_count > 0)
	    successful_join_count--;
	  continue;
	}

    if (!IsOper(source_p))
     check_spambot_warning(source_p, name);
      
      /* can_join checks for +i key, bans etc */
      if ( (i = can_join(source_p, chptr, key)) )
	{
	  sendto_one(source_p,
		     form_str(i), me.name, parv[0], name);
	  if(successful_join_count > 0)
	    successful_join_count--;
	  continue;
	}

      /* add the user to the channel */
      add_user_to_channel(chptr, source_p, flags);

      /* we send the user their join here, because we could have to
       * send a mode out next.
       */
      sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN :%s",
			   source_p->name,
			   source_p->username,
			   source_p->host,
			   chptr->chname);

      /* if theyre joining opped (ie, new chan or joining one thats
       * persisting) then set timestamp to current, set +nt and
       * broadcast the sjoin with its old modes, or +nt.
       */
      if (flags & CHFL_CHANOP)
	{
          char mbuf[MODEBUFLEN];
          char pbuf[MODEBUFLEN];

	  chptr->channelts = CurrentTime;
          chptr->mode.mode |= MODE_TOPICLIMIT;
          chptr->mode.mode |= MODE_NOPRIVMSGS;

	  sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s +nt",
			       me.name, chptr->chname);

          if(*chptr->chname == '#')
          {
            channel_modes(chptr, source_p, mbuf, pbuf);

            strlcat(mbuf, " ", sizeof(mbuf));

            if(pbuf[0] != '\0')
              strlcat(mbuf, pbuf, sizeof(mbuf));

            /* note: mbuf here will have a trailing space.  we add one above,
             * and channel_modes() will leave a trailing space on pbuf if
             * its used --fl
             */
	    sendto_server(client_p, chptr, NOCAPS, NOCAPS,
                          ":%s SJOIN %lu %s %s:@%s",
                          me.name, (unsigned long) chptr->channelts, 
                          chptr->chname, mbuf, parv[0]);
          }

          /* drop our +beI modes */
          free_channel_list(&chptr->banlist);
          free_channel_list(&chptr->exceptlist);
          free_channel_list(&chptr->invexlist);
	}
      else 
	{
	  sendto_server(client_p, chptr, NOCAPS, NOCAPS,
                        ":%s SJOIN %lu %s + :%s",
                        me.name, (unsigned long) chptr->channelts,
                        chptr->chname, parv[0]);
        }

      del_invite(chptr, source_p);
      
      if (chptr->topic != NULL)
	{
	  sendto_one(source_p, form_str(RPL_TOPIC), me.name,
		     parv[0], chptr->chname, chptr->topic);

          sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
                     me.name, parv[0], chptr->chname,
                     chptr->topic_info,
                     chptr->topic_time);
	}

      channel_member_names(source_p, chptr, chptr->chname, 1);

      if(successful_join_count)
	source_p->localClient->last_join_time = CurrentTime;
    }
}
Example #2
0
/*
 * m_topic
 *      parv[1] = channel name
 *	parv[2] = new topic, if setting topic
 */
static int
m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	char *p = NULL;
	const char *name;
	int operspy = 0;

	if((p = strchr(parv[1], ',')))
		*p = '\0';

	name = parv[1];

	if(IsOperSpy(source_p) && parv[1][0] == '!')
	{
		name++;
		operspy = 1;

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

	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	chptr = find_channel(name);

	if(chptr == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				form_str(ERR_NOSUCHCHANNEL), name);
		return 0;
	}

	/* setting topic */
	if(parc > 2)
	{
		msptr = find_channel_membership(chptr, source_p);

		if(msptr == NULL)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), name);
			return 0;
		}

		if(MyClient(source_p) && !is_chanop_voiced(msptr) &&
				!IsOper(source_p) &&
				!add_channel_target(source_p, chptr))
		{
			sendto_one(source_p, form_str(ERR_TARGCHANGE),
				   me.name, source_p->name, chptr->chname);
			return 0;
		}

		if(((chptr->mode.mode & MODE_TOPICLIMIT) == 0 ||
					get_channel_access(source_p, msptr) >= CHFL_CHANOP) &&
				(!MyClient(source_p) ||
				 can_send(chptr, source_p, msptr)))
		{
			char topic_info[USERHOST_REPLYLEN];
			rb_sprintf(topic_info, "%s!%[email protected]%s",
					source_p->name, source_p->username, source_p->host);
			set_channel_topic(chptr, parv[2], topic_info, rb_current_time());

			sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
					":%s TOPIC %s :%s",
					use_id(source_p), chptr->chname,
					chptr->topic == NULL ? "" : chptr->topic);
			sendto_channel_local(ALL_MEMBERS,
					chptr, ":%s!%[email protected]%s TOPIC %s :%s",
					source_p->name, source_p->username,
					source_p->host, chptr->chname,
					chptr->topic == NULL ? "" : chptr->topic);
		}
		else
			sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
					get_id(&me, source_p),
					get_id(source_p, source_p), name);
	}
	else if(MyClient(source_p))
	{
		if(operspy)
			report_operspy(source_p, "TOPIC", chptr->chname);
		if(!IsMember(source_p, chptr) && SecretChannel(chptr) &&
				!operspy)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), name);
			return 0;
		}
		if(chptr->topic == NULL)
			sendto_one(source_p, form_str(RPL_NOTOPIC),
					me.name, source_p->name, name);
		else
		{
			sendto_one(source_p, form_str(RPL_TOPIC),
					me.name, source_p->name, chptr->chname, chptr->topic);

			sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
					me.name, source_p->name, chptr->chname,
					chptr->topic_info,
					(unsigned long)chptr->topic_time);
		}
	}

	return 0;
}
Example #3
0
/*
 * send_conf_options
 *
 * inputs	- client pointer to send to
 * output	- none
 * side effects	- send config options to client
 */
static void
send_conf_options(struct Client *source_p)
{
	int i = 0;

	/*
	 * Parse the info_table[] and do the magic.
	 */
	for(i = 0; info_table[i].name; i++)
	{
		switch (info_table[i].output_type)
		{
			/*
			 * For "char *" references
			 */
		case OUTPUT_STRING:
			{
				const char *option = *(info_table[i].option.pstring);

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option ? option : "NONE",
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}
			/*
			 * For "char foo[]" references
			 */
		case OUTPUT_STRING_PTR:
			{
				const char *option = info_table[i].option.string;

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   EmptyString(option) ? "NONE" : option,
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}
			/*
			 * Output info_table[i].option as a decimal value.
			 */
		case OUTPUT_DECIMAL:
			{
				int option = *info_table[i].option.decimal_ptr;

				sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option,
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}

			/*
			 * Output info_table[i].option as a decimal value.
			 */
		case OUTPUT_DECIMAL_RAW:
			{
				int option = info_table[i].option.decimal;

				sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option,
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}

			/*
			 * Output info_table[i].option as "ON" or "OFF"
			 */
		case OUTPUT_BOOLEAN:
			{
				int option = *(info_table[i].option.decimal_ptr);

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option ? "ON" : "OFF",
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}
			/*
			 * Output info_table[i].option as "YES" or "NO"
			 */
		case OUTPUT_BOOLEAN_YN:
			{
				int option = *(info_table[i].option.decimal_ptr);

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option ? "YES" : "NO",
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}


		case OUTPUT_BOOLEAN_RAW:
			{
				int option = info_table[i].option.decimal;

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option ? "ON" : "OFF",
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}
			/*
			 * Output info_table[i].option as "YES" or "NO"
			 */
		case OUTPUT_BOOLEAN_RAW_YN:
			{
				int option = info_table[i].option.decimal;

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option ? "YES" : "NO",
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}

		case OUTPUT_BOOLEAN2:
			{
				int option = *info_table[i].option.decimal_ptr;

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   me.name, RPL_INFO, source_p->name,
					   info_table[i].name,
					   option ? ((option == 1) ? "MASK" : "YES") : "NO",
					   info_table[i].desc ? info_table[i].desc : "<none>");
			}	/* switch (info_table[i].output_type) */
		}
	}			/* forloop */

	sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
		   get_id(&me, source_p), RPL_INFO,
		   get_id(source_p, source_p),
		   "io_type", rb_get_iotype(), "Method of Multiplexed I/O");

	/* Don't send oper_only_umodes...it's a bit mask, we will have to decode it
	 ** in order for it to show up properly to opers who issue INFO
	 */

	sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), "");
}
Example #4
0
static void 
ms_cburst(struct Client *client_p, struct Client *source_p,
          int parc, char *parv[])
{
  char *name;
  char *nick;
  const char *key;
  struct Channel *chptr;

  if (parc < 2 || *parv[1] == '\0' )
     return;

  name = parv[1];

  if (parc > 2)
    nick = parv[2];
  else
    nick = NULL;

  if (parc > 3)
    key = parv[3];
  else
    key = "";

#ifdef DEBUGLL
  sendto_gnotice_flags(UMODE_ALL, L_ALL, me.name, &me, NULL, "CBURST called by %s for %s %s %s",
                       client_p->name, name, nick ? nick : "", key ? key : "");
#endif
  if ((chptr = hash_find_channel(name)) == NULL)
  {
    if ((!nick) || (nick && *nick != '!'))
    {
      if (!check_channel_name(name, 0))
      {
        sendto_gnotice_flags(UMODE_DEBUG, L_ALL, me.name, &me, NULL,
                             "*** Too long or invalid channel name from %s: %s",
                             client_p->name, name);
        return;
      }

      chptr = make_channel(name);
      chptr->channelts = (time_t)(-1); /* highest possible TS so its always
					* over-ruled
                                        */
    }
    else if(nick && *nick=='!')
    {
      sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
                 me.name, nick+1, name);
      return;
    }
  }

  if (IsCapable(client_p,CAP_LL))
  {
    burst_channel(client_p,chptr);

    if (nick)
      sendto_one(client_p, ":%s LLJOIN %s %s %s",
                 me.name, name, nick, key);
  }
  else
  {
    sendto_gnotice_flags(UMODE_ALL, L_ALL, me.name, &me, NULL,
                         "*** CBURST request received from non LL capable server! [%s]",
                         client_p->name);
    }
}
Example #5
0
/*
 * mo_forcepart
 *	parv[1] = forcepart victim
 *	parv[2] = channels to part
 *	parv[3] = reason
 */
static int
mo_forcepart(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Client *target_p;
	const char *user, *channels, *reason;
	const char default_reason[] = "Leaving";
	int chasing = 0;

	user = parv[1];
	channels = parv[2];

	if(!IsOperLocalForce(source_p))
	{
		sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "local_force");
		return 0;
	}

	/* if target_p == NULL then let the oper know */
	if((target_p = find_chasing(source_p, user, &chasing)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, user);
		return 0;
	}

	if(EmptyString(channels))
	{
		sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "FORCEPART");
		return 0;
	}

	if(EmptyString(parv[3]))
		reason = default_reason;
	else
	{
		char *s;
		s = LOCAL_COPY(parv[3]);
		if(strlen(s) > (size_t) REASONLEN)
			s[REASONLEN] = '\0';
		reason = s;
	}

	if(!IsClient(target_p))
		return 0;

	if(!MyClient(target_p) && (!IsOperGlobalForce(source_p)))
	{
		sendto_one_notice(source_p, ":Nick %s is not on your server and you do not have the global_force flag",
				  target_p->name);
		return 0;
	}

	sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
			       "Received FORCEPART message for %s!%[email protected]%s. From %s (Channels: %s)",
			       target_p->name, target_p->username, target_p->host, source_p->name, channels);
	ilog(L_MAIN, "FORCEPART called for %s %s by %s!%[email protected]%s (part reason %s)",
	     user, channels, source_p->name, source_p->username, source_p->host, reason);

	if(!MyClient(target_p))
	{
		struct Client *cptr = target_p->servptr;
		sendto_one(cptr, ":%s ENCAP %s FORCEPART %s :%s", 
			   get_id(source_p, cptr), cptr->name, get_id(target_p, cptr), channels);
		return 0;
	}

	forcepart_channels(client_p, source_p, target_p, channels, reason);

	return 0;
}
Example #6
0
/*
 * m_challenge - generate RSA challenge for wouldbe oper
 * parv[0] = sender prefix
 * parv[1] = operator to challenge for, or +response
 *
 */
static void
m_challenge(struct Client *client_p, struct Client *source_p,
            int parc, char *parv[])
{
  char *challenge = NULL;
  struct MaskItem *conf = NULL;

  if (*parv[1] == '+')
  {
    /* Ignore it if we aren't expecting this... -A1kmm */
    if (source_p->localClient->response == NULL)
      return;

    if (irccmp(source_p->localClient->response, ++parv[1]))
    {
      sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name,
                 source_p->name);
      failed_challenge_notice(source_p, source_p->localClient->auth_oper,
                              "challenge failed");
      return;
    }
    
    conf = find_exact_name_conf(CONF_OPER, source_p,
                                source_p->localClient->auth_oper, NULL, NULL);
    if (conf == NULL)
    {
      /* XXX: logging */
      sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
      return;
    }

    if (attach_conf(source_p, conf) != 0)
    {
      sendto_one(source_p,":%s NOTICE %s :Can't attach conf!",
		 me.name, source_p->name);   
      failed_challenge_notice(source_p, conf->name, "can't attach conf!");
      return;
    }

    ++conf->count;
    oper_up(source_p);

    ilog(LOG_TYPE_OPER, "OPER %s by %s!%[email protected]%s",
	 source_p->localClient->auth_oper, source_p->name, source_p->username,
	 source_p->host);

    MyFree(source_p->localClient->response);
    MyFree(source_p->localClient->auth_oper);
    source_p->localClient->response  = NULL;
    source_p->localClient->auth_oper = NULL;
    return;
  }

  MyFree(source_p->localClient->response);
  MyFree(source_p->localClient->auth_oper);
  source_p->localClient->response  = NULL;
  source_p->localClient->auth_oper = NULL;

  conf = find_exact_name_conf(CONF_OPER, source_p, parv[1], NULL, NULL);

  if (!conf)
  {
    sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
    conf = find_exact_name_conf(CONF_OPER, NULL, parv[1], NULL, NULL);
    failed_challenge_notice(source_p, parv[1], (conf != NULL)
                            ? "host mismatch" : "no oper {} block");
    return;
  }

  if (conf->rsa_public_key == NULL)
  {
    sendto_one (source_p, ":%s NOTICE %s :I'm sorry, PK authentication "
		"is not enabled for your oper{} block.", me.name,
		source_p->name);
    return;
  }

  if (!generate_challenge(&challenge, &(source_p->localClient->response),
                          conf->rsa_public_key))
    sendto_one(source_p, form_str(RPL_RSACHALLENGE),
               me.name, source_p->name, challenge);

  source_p->localClient->auth_oper = xstrdup(conf->name);
  MyFree(challenge);
}
Example #7
0
/*
** m_pong
**      parv[0] = sender prefix
**      parv[1] = origin
**      parv[2] = destination
*/
int     m_pong(struct Client *cptr,
               struct Client *sptr,
               int parc,
               char *parv[])
{
  struct Client *acptr = NULL;
  char  *origin, *destination;

  if (parc < 2 || *parv[1] == '\0')
    {
      sendto_one(sptr, form_str(ERR_NOORIGIN), me.name, parv[0]);
      return 0;
    }

  origin = parv[1];
  destination = parv[2];

#ifdef HLC
        /* for HLC --fabulous */
        if ((IsServer(cptr)) && (parv[2]) && (IsDigit(*parv[2]))) {
          sentping = 0;
          receivedat = atoi(parv[2]);
        }
#endif

  /* Now attempt to route the PONG, comstud pointed out routable PING
   * is used for SPING.  routable PING should also probably be left in
   *        -Dianora
   * That being the case, we will route, but only for registered clients (a
   * case can be made to allow them only from servers). -Shadowfax
   */
  if (!EmptyString(destination) && irccmp(destination, me.name) != 0
                && IsRegistered(sptr))
    {
      if ((acptr = find_client(destination, NULL)) ||
          (acptr = find_server(destination)))
        sendto_one(acptr,":%s PONG %s %s",
                   parv[0], origin, destination);
      else
        {
          sendto_one(sptr, form_str(ERR_NOSUCHSERVER),
                     me.name, parv[0], destination);
          return 0;
        }
    }
  else
    {
      if (MyConnect(sptr))
      {
        sptr->flags &= ~FLAGS_PINGSENT;
#ifdef NEED_SPLITCODE
#ifdef SPLIT_PONG
        if (IsServer(sptr))
          got_server_pong = 1;
#endif
#endif
        if(MyClient(sptr) && cptr->user)
          check_idle_actions(cptr);                
      }
    }
  return 0;
}
Example #8
0
/*
 * m_htm - HTM command handler
 * high traffic mode info
 */
int m_htm(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  char *command;

  if (!MyClient(sptr) || !IsOper(sptr))
    {
      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
      return 0;
    }
  sendto_one(sptr,
        ":%s NOTICE %s :HTM is %s(%d), %s. Max rate = %dk/s. Current = %.1fk/s recv, %.1fk/s sent", 
          me.name, parv[0], LIFESUX ? "ON" : "OFF", LIFESUX,
          NOISYHTM ? "NOISY" : "QUIET",
       	  LRV, currlife, cursend);		  
  if (parc > 1)
    {
      command = parv[1];
      if (!irccmp(command,"TO"))
        {
          if (parc > 2)
            {
              int new_value = atoi(parv[2]);
              if (new_value < 10)
                {
                  sendto_one(sptr, ":%s NOTICE %s :\002Cannot set LRV < 10!\002",
                             me.name, parv[0]);
                }
              else
                LRV = new_value;
              sendto_one(sptr, ":%s NOTICE %s :NEW Max rate = %dk/s. Current = %.1fk/s",
                         me.name, parv[0], LRV, currlife);
              sendto_realops("%s!%[email protected]%s set new HTM rate to %dk/s (%.1fk/s current)",
                             parv[0], sptr->username, sptr->host,
                             LRV, currlife);
            }
          else 
            sendto_one(sptr, ":%s NOTICE %s :LRV command needs an integer parameter",me.name, parv[0]);
        }
      else
        {
          if (!irccmp(command,"ON"))
            {
              LIFESUX = 1;
              sendto_one(sptr, ":%s NOTICE %s :HTM is now ON.", me.name, parv[0]);
              sendto_ops("Entering high-traffic mode: Forced by %s!%[email protected]%s",
                         parv[0], sptr->username, sptr->host);
              LCF = 30; /* 30s */
            }
          else if (!irccmp(command,"OFF"))
            {
              LIFESUX = 0;
              LCF = LOADCFREQ;
              sendto_one(sptr, ":%s NOTICE %s :HTM is now OFF.", me.name, parv[0]);
              sendto_ops("Resuming standard operation: Forced by %s!%[email protected]%s",
                         parv[0], sptr->username, sptr->host);
            }
          else if (!irccmp(command,"QUIET"))
            {
              sendto_ops("HTM is now QUIET");
              NOISYHTM = NO;
            }
          else if (!irccmp(command,"NOISY"))
            {
              sendto_ops("HTM is now NOISY");
              NOISYHTM = YES;
            }
          else
            sendto_one(sptr,
                       ":%s NOTICE %s :Commands are:HTM [ON] [OFF] [TO int] [QUIET] [NOISY]",
                       me.name, parv[0]);
        }
    }
  return 0;
}
Example #9
0
/* parse()
 *
 * given a raw buffer, parses it and generates parv, parc and sender
 */
void
parse(struct Client *client_p, char *pbuffer, char *bufend)
{
	struct Client *from = client_p;
	char *ch;
	char *s;
	char *end;
	int i = 1;
	char *numeric = 0;
	struct Message *mptr;

	s_assert(MyConnect(client_p));
	if(IsAnyDead(client_p))
		return;

	for(ch = pbuffer; *ch == ' '; ch++)	/* skip spaces */
		/* null statement */ ;

	if(from->name != NULL)
		para[0] = LOCAL_COPY(from->name);
	else
		para[0] = NULL;

	if(*ch == ':')
	{
		ch++;

		/* point sender to the sender param */
		sender = ch;

		if((s = strchr(ch, ' ')))
		{
			*s = '\0';
			s++;
			ch = s;
		}

		if(*sender && IsServer(client_p))
		{
			from = find_client(sender);

			/* didnt find any matching client, issue a kill */
			if(from == NULL)
			{
				ServerStats.is_unpf++;
				remove_unknown(client_p, sender, pbuffer);
				return;
			}

			para[0] = LOCAL_COPY(from->name);

			/* fake direction, hmm. */
			if(from->from != client_p)
			{
				ServerStats.is_wrdi++;
				cancel_clients(client_p, from);
				return;
			}
		}
		while(*ch == ' ')
			ch++;
	}

	if(*ch == '\0')
	{
		ServerStats.is_empt++;
		return;
	}

	/* at this point there must be some sort of command parameter */

	/*
	 * Extract the command code from the packet.  Point s to the end
	 * of the command code and calculate the length using pointer
	 * arithmetic.  Note: only need length for numerics and *all*
	 * numerics must have parameters and thus a space after the command
	 * code. -avalon
	 */

	/* EOB is 3 chars long but is not a numeric */

	if(*(ch + 3) == ' ' &&	/* ok, lets see if its a possible numeric.. */
	   IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)))
	{
		mptr = NULL;
		numeric = ch;
		ServerStats.is_num++;
		s = ch + 3;	/* I know this is ' ' from above if */
		*s++ = '\0';	/* blow away the ' ', and point s to next part */
	}
	else
	{
		int ii = 0;

		if((s = strchr(ch, ' ')))
			*s++ = '\0';

		mptr = hash_parse(ch);

		/* no command or its encap only, error */
		if(!mptr || !mptr->cmd)
		{
			/*
			 * Note: Give error message *only* to recognized
			 * persons. It's a nightmare situation to have
			 * two programs sending "Unknown command"'s or
			 * equivalent to each other at full blast....
			 * If it has got to person state, it at least
			 * seems to be well behaving. Perhaps this message
			 * should never be generated, though...  --msa
			 * Hm, when is the buffer empty -- if a command
			 * code has been found ?? -Armin
			 */
			if(pbuffer[0] != '\0')
			{
				if(IsClient(from))
					sendto_one(from, form_str(ERR_UNKNOWNCOMMAND),
						   me.name, from->name, ch);
			}
			ServerStats.is_unco++;
			return;
		}

		ii = bufend - ((s) ? s : ch);
		mptr->bytes += ii;
	}

	end = bufend - 1;

	/* XXX this should be done before parse() is called */
	if(*end == '\n')
		*end-- = '\0';
	if(*end == '\r')
		*end = '\0';

	if(s != NULL)
		i = string_to_array(s, para);

	if(mptr == NULL)
	{
		do_numeric(numeric, client_p, from, i, para);
		return;
	}

	if(handle_command(mptr, client_p, from, i,	/* XXX discards const!!! */
			  (const char **)para) < -1)
	{
		char *p;
		for(p = pbuffer; p <= end; p += 8)
		{
			/* HACK HACK */
			/* Its expected this nasty code can be removed
			 * or rewritten later if still needed.
			 */
			if((unsigned long)(p + 8) > (unsigned long)end)
			{
				for(; p <= end; p++)
				{
					ilog(L_MAIN, "%02x |%c", p[0], p[0]);
				}
			}
			else
				ilog(L_MAIN,
				     "%02x %02x %02x %02x %02x %02x %02x %02x |%c%c%c%c%c%c%c%c",
				     p[0], p[1], p[2], p[3], p[4], p[5],
				     p[6], p[7], p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
		}
	}

}
Example #10
0
static int
m_cmessage(int p_or_n, const char *command,
	   struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Client *target_p;
	struct Channel *chptr;
	struct membership *msptr;

	if(!IsFloodDone(source_p))
		flood_endgrace(source_p);

	if((target_p = find_named_person(parv[1])) == NULL)
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_NOSUCHNICK,
					   form_str(ERR_NOSUCHNICK), parv[1]);
		return 0;
	}

	if((chptr = find_channel(parv[2])) == NULL)
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
					   form_str(ERR_NOSUCHCHANNEL), parv[2]);
		return 0;
	}

	if((msptr = find_channel_membership(chptr, source_p)) == NULL)
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					   form_str(ERR_NOTONCHANNEL), chptr->chname);
		return 0;
	}

	if(!is_chanop_voiced(msptr))
	{
		if(p_or_n != NOTICE)
			sendto_one(source_p, form_str(ERR_VOICENEEDED),
				   me.name, source_p->name, chptr->chname);
		return 0;
	}

	if(!IsMember(target_p, chptr))
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
					   form_str(ERR_USERNOTINCHANNEL),
					   target_p->name, chptr->chname);
		return 0;
	}

	if(MyClient(target_p) && IsSetCallerId(target_p) &&
	   !accept_message(source_p, target_p) && !IsOper(source_p))
	{
		if(p_or_n != NOTICE)
			sendto_one_numeric(source_p, ERR_TARGUMODEG,
					   form_str(ERR_TARGUMODEG), target_p->name);

		if((target_p->localClient->last_caller_id_time +
		    ConfigFileEntry.caller_id_wait) < rb_current_time())
		{
			if(p_or_n != NOTICE)
				sendto_one_numeric(source_p, RPL_TARGNOTIFY,
						   form_str(RPL_TARGNOTIFY), target_p->name);

			sendto_one(target_p, form_str(RPL_UMODEGMSG),
				   me.name, target_p->name, source_p->name,
				   source_p->username, source_p->host);

			target_p->localClient->last_caller_id_time = rb_current_time();
		}

		return 0;
	}

	if(p_or_n != NOTICE)
		source_p->localClient->last = rb_current_time();

	sendto_anywhere(target_p, source_p, command, ":%s", parv[3]);
	return 0;
}
Example #11
0
/*
** m_whois
**      parv[0] = sender prefix
**      parv[1] = nickname masklist
*/
int     m_whois(struct Client *cptr,
                struct Client *sptr,
                int parc,
                char *parv[])
{
  static anUser UnknownUser =
  {
    NULL,       /* next */
    NULL,       /* channel */
    NULL,       /* invited */
	NULL,		/* silence */
    NULL,       /* away */
    0,          /* last */
    1,          /* refcount */
    0,          /* joined */
    "<Unknown>"         /* server */
  };
  static char rpl_oper[] = "an IRC Operator";
  static char rpl_locop[] = "an IRC Operator - Local IRC Operator";
  static char rpl_sadmin[] = "an IRC Operator - Services Administrator";
  static char rpl_admin[] = "an IRC Operator - Server Administrator";   
  static char rpl_tadmin[] = "an IRC Operator - Technical Administrator";
  static char rpl_nadmin[] = "an IRC Operator - Network Administrator"; 
  
  Link  *lp;
  anUser        *user;
  struct Client *acptr, *a2cptr;
  aChannel *chptr;
  char  *nick, *name;
  /* char  *tmp; */
  char  *p = NULL;
  int   found, len, mlen;
  static time_t last_used=0L;
  char *nick_match=NULL, *user_match=NULL, *host_match=NULL, *server_match=NULL;
  char *name_match=NULL;
  int found_mode;
  int hits = 0;
  char *mename = me.name;

  if(sptr->user && sptr->user->vlink)
    mename = sptr->user->vlink->name;
  
  if (parc < 2)
    {
      sendto_one(sptr, form_str(ERR_NONICKNAMEGIVEN),
                 mename, parv[0]);
      return 0;
    }

  if(parc > 2)
    {
      if (hunt_server(cptr,sptr,":%s WHOIS %s :%s", 1,parc,parv) !=
          HUNTED_ISME)
        return 0;
      parv[1] = parv[2];
    }

  if(!IsAnOper(sptr) && !MyConnect(sptr)) /* pace non local requests */
    {
      if((last_used + WHOIS_WAIT) > CurrentTime)
        {
          /* Unfortunately, returning anything to a non local
           * request =might= increase sendq to be usable in a split hack
           * Sorry gang ;-( - Dianora
           */
          return 0;
        }
      else
        {
          last_used = CurrentTime;
        }
    }

  /* Multiple whois from remote hosts, can be used
   * to flood a server off. One could argue that multiple whois on
   * local server could remain. Lets think about that, for now
   * removing it totally. 
   * -Dianora 
   */

  /*  for (tmp = parv[1]; (nick = strtoken(&p, tmp, ",")); tmp = NULL) */
  nick = parv[1];
  p = strchr(parv[1],',');
  if(p)
    *p = '\0';

    {
      int       invis, member, wilds;
      found = 0;
      (void)collapse(nick);
      wilds = (nick[0]=='$' || strchr(nick, '?') || strchr(nick, '*'));
      /*
      ** We're no longer allowing remote users to generate
      ** requests with wildcards.
      */
      if (wilds && !IsAnOper(sptr))
        {
          sendto_one(sptr, form_str(ERR_NOSUCHNICK),
                     mename, parv[0], nick);
          return 0;
        }
      /*        continue; */

      /* If the nick doesn't have any wild cards in it,
       * then just pick it up from the hash table
       * - Dianora 
       */

      if(!wilds)
        {
          acptr = hash_find_client(nick,(struct Client *)NULL);
          if(!acptr)
            {
              sendto_one(sptr, form_str(ERR_NOSUCHNICK),
                         mename, parv[0], nick);

              sendto_one(sptr, form_str(RPL_ENDOFWHOIS),
                         mename, parv[0], parv[1]);
						 
              return 0;
              /*              continue; */
            }
          if(IsStealth(acptr)) { 
	    sendto_one(sptr, form_str(ERR_NOSUCHNICK), mename,
	     parv[0], nick);
	     return 0; // Add by ^Stinger^ after the idea of Soldier (:
	  } 
	  if(!IsPerson(acptr))
            {
              sendto_one(sptr, form_str(RPL_ENDOFWHOIS),
                         mename, parv[0], parv[1]);
              return 0;
            }
            /*      continue; */

          user = acptr->user ? acptr->user : &UnknownUser;
          name = (!*acptr->name) ? "?" : acptr->name;
          invis = IsInvisible(acptr);
          member = (user->channel) ? 1 : 0;

          a2cptr = find_server(user->server);
          
          sendto_one(sptr, form_str(RPL_WHOISUSER), mename,
        	    parv[0], name, acptr->username, acptr->host, acptr->info);

	  if((IsOper(sptr) || (acptr == sptr)) && WhoisExtension)
	  {
		sendto_one(sptr, form_str(RPL_WHOISREALHOST), mename,
		    parv[0], name, acptr->realhost);
	  }

          mlen = strlen(mename) + strlen(parv[0]) + 6 +
            strlen(name);
			
          *buf = '\0';			
          if (IsSsl(acptr))
          {
              sendto_one(sptr, form_str(RPL_WHOISSECURE), mename, parv[0], parv[1]);
          }

		  if(((!IsPrivate(acptr) || IsOper(sptr)) || (acptr==sptr))
		  && !IsStealth(acptr))
          for (len = 0, *buf = '\0', lp = user->channel; lp;
               lp = lp->next)
            {
              chptr = lp->value.chptr;
              if (ShowChannel(sptr, chptr))
                {
                  if (len + strlen(chptr->chname)
                      > (size_t) BUFSIZE - 4 - mlen)
                    {
                      sendto_one(sptr,
                                 ":%s %d %s %s :%s",
                                 mename,
                                 RPL_WHOISCHANNELS,
                                 parv[0], name, buf);
                      *buf = '\0';
                      len = 0;
                    }

		  found_mode = user_channel_mode(acptr, chptr);
#ifdef HIDE_OPS
		  if(is_chan_op(sptr,chptr))
#endif
		    {
		      if(found_mode & CHFL_CHANOP)
			*(buf + len++) = '@';
#ifdef HALFOPS
                     else if (found_mode & CHFL_HALFOP)
                       *(buf + len++) = '%';
#endif
		      else if (found_mode & CHFL_VOICE)
			*(buf + len++) = '+';
		    }
                  if (len)
                    *(buf + len) = '\0';
                  (void)strcpy(buf + len, chptr->chname);
                  len += strlen(chptr->chname);
                  (void)strcat(buf + len, " ");
                  len++;
                }
            }
          if (buf[0] != '\0')
            sendto_one(sptr, form_str(RPL_WHOISCHANNELS),
                       mename, parv[0], name, buf);
          if(IsAnOper(sptr) || !HideServerOnWhois)
            {
#ifdef SERVERHIDE
            if (!(IsAnOper(sptr) || acptr == sptr))
              sendto_one(sptr, form_str(RPL_WHOISSERVER),
                       mename, parv[0], name, NetworkName,
                       NetworkDesc);
            else
#endif
            if(acptr->user && acptr->user->vlink)
              sendto_one(sptr, form_str(RPL_WHOISSERVER),
                     mename, parv[0], name, user->vlink->name,
                     user->vlink->passwd);
            else
              {
                if(!IsService(acptr) || IsAnOper(sptr) || !HideServicesServer)
                sendto_one(sptr, form_str(RPL_WHOISSERVER),
                     mename, parv[0], name, user->server,
                     a2cptr?a2cptr->info:"*Not On This Net*");
              }
	    } /* if(IsAnOper(sptr) || HideServerOnWhois) */
	  if (IsIdentified(acptr))
            sendto_one(sptr, form_str(RPL_WHOISIDENTIFIED),
                       mename, parv[0], name);

          if (IsHelper(acptr))
        	sendto_one(sptr, form_str(RPL_WHOISHELPOP),
                           mename, parv[0], name);
					   
          if(IsOper(sptr) && WhoisExtension)
	  {
	    sendto_one(sptr, form_str(RPL_WHOISMODE),
		mename, parv[0], name, get_mode_string(acptr));
	  }
	  
	  if (user->away)
            sendto_one(sptr, form_str(RPL_AWAY), mename,
                       parv[0], name, user->away);
	if(!IsHideOper(acptr) || IsOper(sptr))
	  {	
	    if (IsNetAdmin(acptr))
              sendto_one(sptr, form_str(RPL_WHOISOPERATOR),   
                      mename, parv[0], name, rpl_nadmin);
	    else if (IsTechAdmin(acptr))
              sendto_one(sptr, form_str(RPL_WHOISOPERATOR),   
                      mename, parv[0], name, rpl_tadmin);						   
            else if (IsSAdmin(acptr))
              sendto_one(sptr, form_str(RPL_WHOISOPERATOR),   
                      mename, parv[0], name, rpl_sadmin);						   
            else if (IsAdmin(acptr))
              sendto_one(sptr, form_str(RPL_WHOISOPERATOR),  
                      mename, parv[0], name, rpl_admin);
            else if (IsOper(acptr))
              sendto_one(sptr, form_str(RPL_WHOISOPERATOR), 
            	mename, parv[0], name, rpl_oper);
            else if (IsLocOp(acptr))
              sendto_one(sptr, form_str(RPL_WHOISOPERATOR),
            	mename, parv[0], name, rpl_locop);
	  }
#ifdef WHOIS_NOTICE
          if ((IsOper(acptr)) && ((acptr)->umodes & UMODE_SPY) &&
              (MyConnect(sptr)) && (IsPerson(sptr)) && (acptr != sptr) && !is_silenced(sptr, acptr))
            sendto_one(acptr,
                       ":%s NOTICE %s :*** Notice -- %s (%[email protected]%s) is doing a /whois on you.",
                       me.name, acptr->name, parv[0], sptr->username,
                       sptr->realhost);
#endif /* #ifdef WHOIS_NOTICE */


          if ((acptr->user
#ifdef SERVERHIDE
              && IsAnOper(sptr)
#endif
              && MyConnect(acptr)))
            sendto_one(sptr, form_str(RPL_WHOISIDLE),
                       mename, parv[0], name,
                       CurrentTime - user->last,
                       acptr->firsttime);
					   
          sendto_one(sptr, form_str(RPL_ENDOFWHOIS), mename, parv[0], parv[1]);
          
          return 0;
          /*      continue; */
        }

      /* wild is true so here we go */
          if(nick[0]==':') /* real name match */
            {
              name_match =  &nick[1];
              nick_match = NULL;
            }
          else
	  if(nick[0]=='$') /* server name match */
	    {
	      server_match = &nick[1];
	      nick_match = NULL;
	    }
	  else
		{
		  host_match = strchr(nick,'@');
		  if(host_match)
			{
			  if(*host_match)
				*(host_match++) = '\0';						  
			  user_match=nick;		  		  
			  if(host_match=='\0')
				host_match="*";		  			
			  if(user_match=='\0')
			  user_match="*";		  
			}
		  else
			nick_match = nick;
		}
		
	  				
      for (acptr = GlobalClientList; acptr;
           acptr = acptr->next)
        {
          if (IsServer(acptr))
            continue;
          /*
           * I'm always last :-) and acptr->next == NULL!!
           */
          if (IsMe(acptr))
            break;
          /*
           * 'Rules' established for sending a WHOIS reply:
           *
           *
           * - if wildcards are being used dont send a reply if
           *   the querier isnt any common channels and the
           *   client in question is invisible and wildcards are
           *   in use (allow exact matches only);
           *
           * - only send replies about common or public channels
           *   the target user(s) are on;
           */

/* If its an unregistered client, ignore it, it can
   be "seen" on a /trace anyway  -Dianora */

          if(!IsRegistered(acptr))
            continue;

          user = acptr->user ? acptr->user : &UnknownUser;
          name = (!*acptr->name) ? "?" : acptr->name;
		  
		  if(  (server_match && !match(server_match, user->server))
		    || (nick_match && !match(nick, name)) 
			|| (host_match && !match(host_match, acptr->realhost)
			   && !match(host_match, acptr->host))
			|| (user_match && !match(user_match, acptr->username))
			|| (name_match &&  !match(name_match, acptr->info))
			)
        	  continue;
			  
		  ++hits;
			  
          a2cptr = find_server(user->server);
          
          sendto_one(sptr, form_str(RPL_WHOISUSER), mename,
                    parv[0], name,
                    acptr->username, 
					IsOper(sptr) ? acptr->realhost : acptr->host,					 
					acptr->info);
					
          found = 1;
          mlen = strlen(mename) + strlen(parv[0]) + 6 +
            strlen(name);
          for (len = 0, *buf = '\0', lp = user->channel; lp;
               lp = lp->next)
            {
              chptr = lp->value.chptr;
              if (ShowChannel(sptr, chptr))
                {
                  if (len + strlen(chptr->chname)
                      > (size_t) BUFSIZE - 4 - mlen)
                    {
                      sendto_one(sptr,
                                 ":%s %d %s %s :%s",
                                 mename,
                                 RPL_WHOISCHANNELS,
                                 parv[0], name, buf);
                      *buf = '\0';
                      len = 0;
                    }
		  found_mode = user_channel_mode(acptr, chptr);
#ifdef HIDE_OPS
                  if(is_chan_op(sptr,chptr))
#endif
		     {
		       if (found_mode & CHFL_CHANOP)
			 *(buf + len++) = '@';
#ifdef HALFOPS
                     else if (found_mode & CHFL_HALFOP)
                        *(buf + len++) = '%';
#endif                                            
		       else if (found_mode & CHFL_VOICE)
			 *(buf + len++) = '+';
		     }
                  if (len)
                    *(buf + len) = '\0';
                  (void)strcpy(buf + len, chptr->chname);
                  len += strlen(chptr->chname);
                  (void)strcat(buf + len, " ");
                  len++;
                }
            }
          if (buf[0] != '\0')
            sendto_one(sptr, form_str(RPL_WHOISCHANNELS),
                       mename, parv[0], name, buf);
         
#ifdef SERVERHIDE
          if (!(IsAnOper(sptr) || acptr == sptr))
            sendto_one(sptr, form_str(RPL_WHOISSERVER),
                       mename, parv[0], name, NetworkName,
                       NetworkDesc);
          else    
#endif
          sendto_one(sptr, form_str(RPL_WHOISSERVER),
                     mename, parv[0], name, user->server,
                     a2cptr?a2cptr->info:"*Not On This Net*");

          if (user->away)
            sendto_one(sptr, form_str(RPL_AWAY), mename,
                       parv[0], name, user->away);



  		  if (IsNetAdmin(acptr))
                sendto_one(sptr, form_str(RPL_WHOISOPERATOR),   
                           mename, parv[0], name, rpl_nadmin);
		  else if (IsTechAdmin(acptr))
                sendto_one(sptr, form_str(RPL_WHOISOPERATOR),   
                           mename, parv[0], name, rpl_tadmin);						   
          else if (IsSAdmin(acptr))
                sendto_one(sptr, form_str(RPL_WHOISOPERATOR),   
                           mename, parv[0], name, rpl_sadmin);						   
          else if (IsAdmin(acptr))
                sendto_one(sptr, form_str(RPL_WHOISOPERATOR),  
                           mename, parv[0], name, rpl_admin);
          else if (IsAnOper(acptr))
                sendto_one(sptr, form_str(RPL_WHOISOPERATOR), 
                           mename, parv[0], name, rpl_oper);


#ifdef WHOIS_NOTICE
          if ((MyOper(acptr)) && ((acptr)->umodes & UMODE_SPY) &&
              (MyConnect(sptr)) && (IsPerson(sptr)) && (acptr != sptr))
            sendto_one(acptr,
                       ":%s NOTICE %s :*** Notice -- %s (%[email protected]%s) is doing a /whois on you.",
                       mename, acptr->name, parv[0], sptr->username,
                       sptr->realhost);
#endif /* #ifdef WHOIS_NOTICE */

          if ((acptr->user
#ifdef SERVERHIDE
              && IsAnOper(sptr) 
#endif                 
              && MyConnect(acptr)))
            sendto_one(sptr, form_str(RPL_WHOISIDLE),
                       mename, parv[0], name,
                       CurrentTime - user->last,
                       acptr->firsttime);

		if(hits>50)
		  {
  			sendto_one(sptr,":%s NOTICE %s :Aborting /whois output as flood prevention",
				mename, sptr->name);			  
			break;
		  }
        }
		
      if (!found)	  
        sendto_one(sptr, form_str(ERR_NOSUCHNICK),
                   mename, parv[0], nick);
	  else
		sendto_one(sptr,":%s NOTICE %s :This /whois matched \2%i\2 user(s)", 
			mename, sptr->name,hits);
      /*
      if (p)
        p[-1] = ',';
        */
    }

  sendto_one(sptr, form_str(RPL_ENDOFWHOIS), mename, parv[0], parv[1]);
  
  return 0;
}
Example #12
0
static void
me_sasl(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
	int parc, const char *parv[])
{
	struct Client *target_p, *agent_p;

	/* Let propagate if not addressed to us, or if broadcast.
	 * Only SASL agents can answer global requests.
	 */
	if(strncmp(parv[2], me.id, 3))
		return;

	if((target_p = find_id(parv[2])) == NULL)
		return;

	if((agent_p = find_id(parv[1])) == NULL)
		return;

	if(source_p != agent_p->servptr) /* WTF?! */
		return;

	/* We only accept messages from SASL agents; these must have umode +S
	 * (so the server must be listed in a service{} block).
	 */
	if(!IsService(agent_p))
		return;

	/* Reject if someone has already answered. */
	if(*target_p->localClient->sasl_agent && strncmp(parv[1], target_p->localClient->sasl_agent, IDLEN))
		return;
	else if(!*target_p->localClient->sasl_agent)
		rb_strlcpy(target_p->localClient->sasl_agent, parv[1], IDLEN);

	if(*parv[3] == 'C')
	{
		sendto_one(target_p, "AUTHENTICATE %s", parv[4]);
		target_p->localClient->sasl_messages++;
	}
	else if(*parv[3] == 'D')
	{
		if(*parv[4] == 'F')
		{
			sendto_one(target_p, form_str(ERR_SASLFAIL), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
			/* Failures with zero messages are just "unknown mechanism" errors; don't count those. */
			if(target_p->localClient->sasl_messages > 0)
			{
				if(*target_p->name)
				{
					target_p->localClient->sasl_failures++;
					target_p->localClient->sasl_next_retry = rb_current_time() + (1 << MIN(target_p->localClient->sasl_failures + 5, 13));
				}
				else if(throttle_add((struct sockaddr*)&target_p->localClient->ip))
				{
					exit_client(target_p, target_p, &me, "Too many failed authentication attempts");
					return;
				}
			}
		}
		else if(*parv[4] == 'S')
		{
			sendto_one(target_p, form_str(RPL_SASLSUCCESS), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
			target_p->localClient->sasl_failures = 0;
			target_p->localClient->sasl_complete = 1;
			ServerStats.is_ssuc++;
		}
		*target_p->localClient->sasl_agent = '\0'; /* Blank the stored agent so someone else can answer */
		target_p->localClient->sasl_messages = 0;
	}
	else if(*parv[3] == 'M')
		sendto_one(target_p, form_str(RPL_SASLMECHS), me.name, EmptyString(target_p->name) ? "*" : target_p->name, parv[4]);
}
Example #13
0
static void
m_authenticate(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
	int parc, const char *parv[])
{
	struct Client *agent_p = NULL;
	struct Client *saslserv_p = NULL;

	/* They really should use CAP for their own sake. */
	if(!IsCapable(source_p, CLICAP_SASL))
		return;

	if(source_p->localClient->sasl_next_retry > rb_current_time())
	{
		sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, EmptyString(source_p->name) ? "*" : source_p->name, msgbuf_p->cmd);
		return;
	}

	if(strlen(client_p->id) == 3)
	{
		exit_client(client_p, client_p, client_p, "Mixing client and server protocol");
		return;
	}

	saslserv_p = find_named_client(ConfigFileEntry.sasl_service);
	if(saslserv_p == NULL || !IsService(saslserv_p))
	{
		sendto_one(source_p, form_str(ERR_SASLABORTED), me.name, EmptyString(source_p->name) ? "*" : source_p->name);
		return;
	}

	if(source_p->localClient->sasl_complete)
	{
		*source_p->localClient->sasl_agent = '\0';
		source_p->localClient->sasl_complete = 0;
	}

	if(strlen(parv[1]) > 400)
	{
		sendto_one(source_p, form_str(ERR_SASLTOOLONG), me.name, EmptyString(source_p->name) ? "*" : source_p->name);
		return;
	}

	if(!*source_p->id)
	{
		/* Allocate a UID. */
		strcpy(source_p->id, generate_uid());
		add_to_id_hash(source_p->id, source_p);
	}

	if(*source_p->localClient->sasl_agent)
		agent_p = find_id(source_p->localClient->sasl_agent);

	if(agent_p == NULL)
	{
		sendto_one(saslserv_p, ":%s ENCAP %s SASL %s %s H %s %s",
					me.id, saslserv_p->servptr->name, source_p->id, saslserv_p->id,
					source_p->host, source_p->sockhost);

		if (source_p->certfp != NULL)
			sendto_one(saslserv_p, ":%s ENCAP %s SASL %s %s S %s %s",
						me.id, saslserv_p->servptr->name, source_p->id, saslserv_p->id,
						parv[1], source_p->certfp);
		else
			sendto_one(saslserv_p, ":%s ENCAP %s SASL %s %s S %s",
						me.id, saslserv_p->servptr->name, source_p->id, saslserv_p->id,
						parv[1]);

		rb_strlcpy(source_p->localClient->sasl_agent, saslserv_p->id, IDLEN);
	}
	else
		sendto_one(agent_p, ":%s ENCAP %s SASL %s %s C %s",
				me.id, agent_p->servptr->name, source_p->id, agent_p->id,
				parv[1]);
	source_p->localClient->sasl_out++;
}
Example #14
0
/*
 * m_forcejoin
 *      parv[1] = user to force
 *      parv[2] = channel to force them into
 */
static int
mo_forcejoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Client *target_p;
	struct Channel *chptr;
	int type;
	char mode;
	char sjmode;
	char *newch;

	if(!IsOperAdmin(source_p))
	{
		sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "forcejoin");
		return 0;
	}

	if((hunt_server(client_p, source_p, ":%s FORCEJOIN %s %s", 1, parc, parv)) != HUNTED_ISME)
		return 0;

	/* if target_p is not existant, print message
	 * to source_p and bail - scuzzy
	 */
	if((target_p = find_client(parv[1])) == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]);
		return 0;
	}

	if(!IsClient(target_p))
		return 0;

	/* select our modes from parv[2] if they exist... (chanop) */
	if(*parv[2] == '@')
	{
		type = CHFL_CHANOP;
		mode = 'o';
		sjmode = '@';
	}
	else if(*parv[2] == '+')
	{
		type = CHFL_VOICE;
		mode = 'v';
		sjmode = '+';
	}
	else
	{
		type = CHFL_PEON;
		mode = sjmode = '\0';
	}

	if(mode != '\0')
		parv[2]++;

	if((chptr = find_channel(parv[2])) != NULL)
	{
		if(IsMember(target_p, chptr))
		{
			/* debugging is fun... */
			sendto_one(source_p, ":%s NOTICE %s :*** Notice -- %s is already in %s",
				   me.name, source_p->name, target_p->name, chptr->chname);
			return 0;
		}

		add_user_to_channel(chptr, target_p, type);

		sendto_server(target_p, chptr, NOCAPS, NOCAPS,
			      ":%s SJOIN %ld %s + :%c%s",
			      me.name, (long)chptr->channelts,
			      chptr->chname, type ? sjmode : ' ', target_p->name);

		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN :%s",
				     target_p->name, target_p->username,
				     target_p->host, chptr->chname);

		if(type)
			sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +%c %s",
					     me.name, chptr->chname, mode, target_p->name);

		if(chptr->topic != NULL)
		{
			sendto_one(target_p, form_str(RPL_TOPIC), me.name,
				   target_p->name, chptr->chname, chptr->topic->topic);
			sendto_one(target_p, form_str(RPL_TOPICWHOTIME),
				   me.name, source_p->name, chptr->chname,
				   chptr->topic->topic_info, chptr->topic->topic_time);
		}

		channel_member_names(chptr, target_p, 1);
	}
	else
	{
		newch = LOCAL_COPY(parv[2]);
		if(!check_channel_name(newch))
		{
			sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name,
				   source_p->name, (unsigned char *)newch);
			return 0;
		}

		/* channel name must begin with & or # */
		if(!IsChannelName(newch))
		{
			sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name,
				   source_p->name, (unsigned char *)newch);
			return 0;
		}

		/* newch can't be longer than CHANNELLEN */
		if(strlen(newch) > CHANNELLEN)
		{
			sendto_one(source_p, ":%s NOTICE %s :Channel name is too long", me.name,
				   source_p->name);
			return 0;
		}

		chptr = get_or_create_channel(target_p, newch, NULL);
		add_user_to_channel(chptr, target_p, CHFL_CHANOP);

		/* send out a join, make target_p join chptr */
		sendto_server(target_p, chptr, NOCAPS, NOCAPS,
			      ":%s SJOIN %ld %s +nt :@%s", me.name,
			      (long)chptr->channelts, chptr->chname, target_p->name);

		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN :%s",
				     target_p->name, target_p->username,
				     target_p->host, chptr->chname);

		chptr->mode.mode |= MODE_TOPICLIMIT;
		chptr->mode.mode |= MODE_NOPRIVMSGS;

		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +nt", me.name, chptr->chname);

		target_p->localClient->last_join_time = rb_time();
		channel_member_names(chptr, target_p, 1);

		/* we do this to let the oper know that a channel was created, this will be
		 * seen from the server handling the command instead of the server that
		 * the oper is on.
		 */
		sendto_one(source_p, ":%s NOTICE %s :*** Notice -- Creating channel %s", me.name,
			   source_p->name, chptr->chname);
	}
	return 0;
}
Example #15
0
/*
** m_away
**      parv[1] = away message
*/
static int
m_away(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	if(MyClient(source_p) && source_p->localClient->next_away &&
			!IsFloodDone(source_p)) 
		flood_endgrace(source_p);

	if(!IsClient(source_p))
		return 0;

	if(parc < 2 || EmptyString(parv[1]))
	{
		/* Marking as not away */
		if(source_p->user->away != NULL)
		{
			/* we now send this only if they were away before --is */
			sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
				      ":%s AWAY", use_id(source_p));
			free_away(source_p);
			
			sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, ":%s!%[email protected]%s AWAY", 
					source_p->name, source_p->username, source_p->host);
		}
		if(MyConnect(source_p))
			sendto_one_numeric(source_p, RPL_UNAWAY, form_str(RPL_UNAWAY));
		return 0;
	}
	
	/* Rate limit this because it is sent to common channels. */
	if (MyClient(source_p)) 
	{
		if(!IsOper(source_p) &&
				source_p->localClient->next_away > rb_current_time())
		{
			sendto_one(source_p, form_str(RPL_LOAD2HI),
					me.name, source_p->name, "AWAY");
			return 0;
		}
		if(source_p->localClient->next_away < rb_current_time() -
				ConfigFileEntry.away_interval)
			source_p->localClient->next_away = rb_current_time();
		else
			source_p->localClient->next_away = rb_current_time() +
				ConfigFileEntry.away_interval; 
	}

	if(source_p->user->away == NULL)
		allocate_away(source_p);
	if(strncmp(source_p->user->away, parv[1], AWAYLEN - 1))
	{
		rb_strlcpy(source_p->user->away, parv[1], AWAYLEN);
		sendto_server(client_p, NULL, CAP_TS6, NOCAPS, 
			      ":%s AWAY :%s", use_id(source_p), source_p->user->away);
	}
	
	if(MyConnect(source_p))
		sendto_one_numeric(source_p, RPL_NOWAWAY, form_str(RPL_NOWAWAY));
	
	sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, ":%s!%[email protected]%s AWAY :%s", 
			source_p->name, source_p->username, source_p->host, 
			source_p->user->away); 
	
	return 0;
}
Example #16
0
/*
 * handle_command
 *
 * inputs	- pointer to message block
 *		- pointer to client
 *		- pointer to client message is from
 *		- count of number of args
 *		- pointer to argv[] array
 * output	- -1 if error from server
 * side effects	-
 */
static int
handle_command(struct Message *mptr, struct Client *client_p,
	       struct Client *from, int i, const char **hpara)
{
	struct MessageEntry ehandler;
	MessageHandler handler = 0;
	static time_t last_warning;

	if(IsAnyDead(client_p))
		return -1;

	if(IsServer(client_p))
		mptr->rcount++;

	mptr->count++;

	/* New patch to avoid server flooding from unregistered connects
	   - Pie-Man 07/27/2000 */

	if(!IsRegistered(client_p))
	{
		/* if its from a possible server connection
		 * ignore it.. more than likely its a header thats sneaked through
		 */

		if(IsAnyServer(client_p) && !(mptr->flags & MFLG_UNREG))
			return (1);
	}

	ehandler = mptr->handlers[from->handler];
	handler = ehandler.handler;

	/* check right amount of params is passed... --is */
	if(i < ehandler.min_para ||
	   (ehandler.min_para && EmptyString(hpara[ehandler.min_para - 1])))
	{
		if(!IsServer(client_p))
		{
			sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS),
				   me.name,
				   EmptyString(client_p->name) ? "*" : client_p->name, mptr->cmd);
			if(MyClient(client_p))
				return (1);
			else
				return (-1);
		}

		sendto_realops_flags(UMODE_ALL, L_ALL,
				     "Dropping server %s due to (invalid) command '%s'"
				     " with only %d arguments (expecting %d).",
				     client_p->name, mptr->cmd, i, ehandler.min_para);
		ilog(L_SERVER,
		     "Insufficient parameters (%d) for command '%s' from %s.",
		     i, mptr->cmd, client_p->name);

		exit_client(client_p, client_p, client_p,
			    "Not enough arguments to server command.");
		return (-1);
	}

	(*handler) (client_p, from, i, hpara);
	if(!IsAnyDead(client_p) && IsCork(client_p) && !IsCapable(client_p, CAP_ZIP))
	{
		if(last_warning + 300 <= rb_time())
		{
			sendto_realops_flags(UMODE_DEBUG, L_ALL,
					     "Bug: client %s was left corked after command %s",
					     client_p->name, mptr->cmd);
			last_warning = rb_time();
		}
		client_p->localClient->cork_count = 0;
		send_pop_queue(client_p);
	}
	return (1);
}
Example #17
0
/*
 * m_topic
 *      parv[1] = channel name
 *	parv[2] = new topic, if setting topic
 */
static int
m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	char *p = NULL;

	if((p = strchr(parv[1], ',')))
		*p = '\0';

	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	if(!IsChannelName(parv[1]))
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	chptr = find_channel(parv[1]);

	if(chptr == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	/* setting topic */
	if(parc > 2)
	{
		msptr = find_channel_membership(chptr, source_p);

		if(msptr == NULL)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					   form_str(ERR_NOTONCHANNEL), parv[1]);
			return 0;
		}

		if((chptr->mode.mode & MODE_TOPICLIMIT) == 0 || is_chanop(msptr))
		{
			char topic_info[USERHOST_REPLYLEN];
			rb_sprintf(topic_info, "%s!%[email protected]%s",
				   source_p->name, source_p->username, source_p->host);
			set_channel_topic(chptr, parv[2], topic_info, rb_time());

			sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
				      ":%s TOPIC %s :%s",
				      source_p->id, chptr->chname,
				      chptr->topic == NULL ? "" : chptr->topic->topic);
			sendto_channel_local(ALL_MEMBERS,
					     chptr, ":%s!%[email protected]%s TOPIC %s :%s",
					     source_p->name, source_p->username,
					     source_p->host, chptr->chname,
					     chptr->topic == NULL ? "" : chptr->topic->topic);
		}
		else
			sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
				   me.name, source_p->name, parv[1]);
	}
	else if(MyClient(source_p))
	{
		if(!IsMember(source_p, chptr) && SecretChannel(chptr))
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					   form_str(ERR_NOTONCHANNEL), parv[1]);
			return 0;
		}
		if(chptr->topic == NULL)
			sendto_one(source_p, form_str(RPL_NOTOPIC),
				   me.name, source_p->name, parv[1]);
		else
		{
			sendto_one(source_p, form_str(RPL_TOPIC),
				   me.name, source_p->name, chptr->chname, chptr->topic->topic);

			sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
				   me.name, source_p->name, chptr->chname,
				   chptr->topic->topic_info, chptr->topic->topic_time);
		}
	}

	return 0;
}
Example #18
0
int
m_not_oper(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	sendto_one_numeric(source_p, ERR_NOPRIVILEGES, form_str(ERR_NOPRIVILEGES));
	return 0;
}
Example #19
0
/*
 * m_ison added by Darren Reed 13/8/91 to act as an efficent user indicator
 * with respect to cpu/bandwidth used. Implemented for NOTIFY feature in
 * clients. Designed to reduce number of whois requests. Can process
 * nicknames in batches as long as the maximum buffer length.
 *
 * format:
 * ISON :nicklist
 */
static void
m_ison(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct Client *target_p;
	char *nick;
	char *p;
	char *current_insert_point, *current_insert_point2;
	int len;
	int i;
	int done = 0;

	current_insert_point2 = buf2;
	*buf2 = '\0';

	ircsprintf(buf, form_str(RPL_ISON), me.name, parv[0]);
	len = strlen(buf);
	current_insert_point = buf + len;

	/* rfc1489 is ambigious about how to handle ISON
	 * this should handle both interpretations.
	 */
	for (i = 1; i < parc; i++)
	{
		for (nick = strtoken(&p, parv[i], " "); nick; nick = strtoken(&p, NULL, " "))
		{
			target_p = find_person(nick);

			if(target_p == NULL && (IsOper(source_p) || !ConfigServerHide.hide_servers))
			{
				target_p = find_server(nick);
			}

			if(target_p != NULL)
			{
				len = strlen(target_p->name);
				if((current_insert_point + (len + 5)) < (buf + sizeof(buf)))
				{
					memcpy((void *) current_insert_point,
					       (void *) target_p->name, len);
					current_insert_point += len;
					*current_insert_point++ = ' ';
				}
				else
				{
					done = 1;
					break;
				}
			}
		}
		if(done)
			break;
	}

	/*  current_insert_point--;
	 *  Do NOT take out the trailing space, it breaks ircII
	 *  --Rodder */

	*current_insert_point = '\0';
	*current_insert_point2 = '\0';

	sendto_one(source_p, "%s", buf);

}
Example #20
0
int
m_registered(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	sendto_one(client_p, form_str(ERR_ALREADYREGISTRED), me.name, source_p->name);
	return 0;
}
Example #21
0
/*
 * send_conf_options
 *
 * inputs	- client pointer to send to
 * output	- none
 * side effects	- send config options to client
 */
static void
send_conf_options(struct Client *source_p)
{
	Info *infoptr;
	int i = 0;

	/*
	 * Now send them a list of all our configuration options
	 * (mostly from config.h)
	 */
	for (infoptr = MyInformation; infoptr->name; infoptr++)
	{
		if(infoptr->intvalue)
		{
			sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
				   get_id(&me, source_p), RPL_INFO,
				   get_id(source_p, source_p),
				   infoptr->name, infoptr->intvalue, 
				   infoptr->desc);
		}
		else
		{
			sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
				   get_id(&me, source_p), RPL_INFO,
				   get_id(source_p, source_p),
				   infoptr->name, infoptr->strvalue, 
				   infoptr->desc);
		}
	}

	/*
	 * Parse the info_table[] and do the magic.
	 */
	for (i = 0; info_table[i].name; i++)
	{
		switch (info_table[i].output_type)
		{
			/*
			 * For "char *" references
			 */
		case OUTPUT_STRING:
			{
				char *option = *((char **) info_table[i].option);

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option ? option : "NONE",
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}
			/*
			 * For "char foo[]" references
			 */
		case OUTPUT_STRING_PTR:
			{
				char *option = (char *) info_table[i].option;

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   EmptyString(option) ? "NONE" : option,
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}
			/*
			 * Output info_table[i].option as a decimal value.
			 */
		case OUTPUT_DECIMAL:
			{
				int option = *((int *) info_table[i].option);

				sendto_one(source_p, ":%s %d %s :%-30s %-5d [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option,
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}

			/*
			 * Output info_table[i].option as "ON" or "OFF"
			 */
		case OUTPUT_BOOLEAN:
			{
				int option = *((int *) info_table[i].option);

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option ? "ON" : "OFF",
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}
			/*
			 * Output info_table[i].option as "YES" or "NO"
			 */
		case OUTPUT_BOOLEAN_YN:
			{
				int option = *((int *) info_table[i].option);

				sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
					   get_id(&me, source_p), RPL_INFO,
					   get_id(source_p, source_p),
					   info_table[i].name,
					   option ? "YES" : "NO",
					   info_table[i].desc ? info_table[i].desc : "<none>");

				break;
			}

		case OUTPUT_BOOLEAN2:
		{
			int option = *((int *) info_table[i].option);

			sendto_one(source_p, ":%s %d %s :%-30s %-5s [%-30s]",
				   me.name, RPL_INFO, source_p->name,
				   info_table[i].name,
				   option ? ((option == 1) ? "MASK" : "YES") : "NO",
				   info_table[i].desc ? info_table[i].desc : "<none>");
		}		/* switch (info_table[i].output_type) */
		}
	}			/* forloop */


	/* Don't send oper_only_umodes...it's a bit mask, we will have to decode it
	 ** in order for it to show up properly to opers who issue INFO
	 */

	sendto_one_numeric(source_p, RPL_INFO, form_str(RPL_INFO), "");
}
Example #22
0
/*
** mo_ojoin
**      parv[0] = sender prefix
**      parv[1] = channel
*/
static void mo_ojoin(struct Client *client_p, struct Client *source_p,
                        int parc, char *parv[])
{
	struct Channel *chptr;
	int move_me = 0;

	/* admins only */
	if (!IsOperAdmin(source_p))
	{
		sendto_one(source_p, ":%s NOTICE %s :You have no A flag", me.name, parv[0]);
		return;
	}

	if (*parv[1] == '@' || *parv[1] == '+')
	{
		parv[1]++;
		move_me = 1;
	}

	chptr = hash_find_channel(parv[1]);

	if(chptr == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
			   me.name, parv[0], parv[1]);
		return;
	}

	if(IsMember(source_p, chptr))
	{
		sendto_one(source_p, ":%s NOTICE %s :Please part %s before using OJOIN",
			   me.name, source_p->name, parv[1]);
		return;
	}

	if (move_me == 1)
		parv[1]--;

	sendto_wallops_flags(UMODE_WALLOP, &me, 
			     "OJOIN called for [%s] by %s!%[email protected]%s",
			     parv[1], source_p->name, source_p->username, source_p->host);
	ilog(L_NOTICE, "OJOIN called for [%s] by %s!%[email protected]%s",
	     parv[1], source_p->name, source_p->username, source_p->host);

	if(*chptr->chname != '&')
		sendto_server(NULL, NULL, NOCAPS, NOCAPS, 
			      ":%s WALLOPS :OJOIN called for [%s] by %s!%[email protected]%s",
			      me.name, parv[1], source_p->name, source_p->username,
			      source_p->host);

	if (*parv[1] == '@') 
	{
		add_user_to_channel(chptr, source_p, CHFL_CHANOP);

		if(*chptr->chname != '&')
			sendto_server(client_p, chptr, NOCAPS, NOCAPS,  
				      ":%s SJOIN %lu %s + :@%s", 
				      me.name, chptr->channelts,
				      chptr->chname, source_p->name);

		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
				     source_p->name, source_p->username,
				     source_p->host, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
				     me.name, chptr->chname, source_p->name);

	}
	else if (*parv[1] == '+')
	{
		add_user_to_channel(chptr, source_p, CHFL_VOICE);

		if(*chptr->chname != '&')
			sendto_server(client_p, chptr, NOCAPS, NOCAPS,  
				      ":%s SJOIN %lu %s + :+%s",
				      me.name, chptr->channelts,
				      chptr->chname, source_p->name);

		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
				     source_p->name, source_p->username,
				     source_p->host, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s",
				     me.name, chptr->chname, source_p->name);
	}
	else
	{
		add_user_to_channel(chptr, source_p, CHFL_PEON);

		if(*chptr->chname != '&')
			sendto_server(client_p, chptr, NOCAPS, NOCAPS,  
				      ":%s SJOIN %lu %s + :%s",
				      me.name, chptr->channelts,
				      chptr->chname, source_p->name);

		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
				     source_p->name, source_p->username,
				     source_p->host, chptr->chname);
	}

	/* send the topic... */
	if (chptr->topic != NULL)
	{
		sendto_one(source_p, form_str(RPL_TOPIC), me.name,
				source_p->name, chptr->chname, chptr->topic);
		sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name,
				source_p->name, chptr->chname, chptr->topic_info,
				chptr->topic_time);
	}

	source_p->localClient->last_join_time = CurrentTime;
	channel_member_names(chptr, source_p, 1);
}
Example #23
0
/* m_kick()
 *  parv[0] = sender prefix
 *  parv[1] = channel
 *  parv[2] = client to kick
 *  parv[3] = kick comment
 */
static void 
m_kick(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  struct Client *who;
  struct Channel *chptr;
  int chasing = 0;
  char *comment;
  char *name;
  char *p = NULL;
  char *user;
  const char *from, *to;
  struct Membership *ms = NULL;
  struct Membership *ms_target;

  if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
  {
    from = me.id;
    to = source_p->id;
  }
  else
  {
    from = me.name;
    to = source_p->name;
  }

  if (*parv[2] == '\0')
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               from, to, "KICK");
    return;
  }

  if (MyClient(source_p) && !IsFloodDone(source_p))
    flood_endgrace(source_p);

  comment = (EmptyString(parv[3])) ? parv[2] : parv[3];
  if (strlen(comment) > (size_t) TOPICLEN)
    comment[TOPICLEN] = '\0';

  name = parv[1];
  while (*name == ',')
    name++;
  if ((p = strchr(name,',')) != NULL)
    *p = '\0';
  if (!*name)
    return;

  if ((chptr = hash_find_channel(name)) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
               from, to, name);
    return;
  }

  if (!IsServer(source_p))
  {
    if ((ms = find_channel_link(source_p, chptr)) == NULL)
    {
      if (MyConnect(source_p))
      {
        sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
                   me.name, source_p->name, name);
        return;
      }
    }

    if (!has_member_flags(ms, CHFL_CHANOWNER) && (chptr->mode.mode & MODE_PEACE))
    {
      /* don't kick in +P mode. */
      sendto_one(source_p, form_str(ERR_CHANPEACE), me.name, source_p->name, name);
      return;
    }

    if (!has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP|CHFL_CHANOWNER))
    {
      /* was a user, not a server, and user isn't seen as a chanop here */
      if (MyConnect(source_p))
      {
        /* user on _my_ server, with no chanops.. so go away */
        sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                   me.name, source_p->name, name);
        return;
      }

      if (chptr->channelts == 0)
      {
        /* If its a TS 0 channel, do it the old way */         
        sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                   from, to, name);
        return;
      }

      /* Its a user doing a kick, but is not showing as chanop locally
       * its also not a user ON -my- server, and the channel has a TS.
       * There are two cases we can get to this point then...
       *
       *     1) connect burst is happening, and for some reason a legit
       *        op has sent a KICK, but the SJOIN hasn't happened yet or 
       *        been seen. (who knows.. due to lag...)
       *
       *     2) The channel is desynced. That can STILL happen with TS
       *        
       *     Now, the old code roger wrote, would allow the KICK to 
       *     go through. Thats quite legit, but lets weird things like
       *     KICKS by users who appear not to be chanopped happen,
       *     or even neater, they appear not to be on the channel.
       *     This fits every definition of a desync, doesn't it? ;-)
       *     So I will allow the KICK, otherwise, things are MUCH worse.
       *     But I will warn it as a possible desync.
       *
       *     -Dianora
       */
    }
  }

  user = parv[2];

  while (*user == ',')
    user++;

  if ((p = strchr(user,',')) != NULL)
    *p = '\0';

  if (!*user)
    return;

  if ((who = find_chasing(source_p, user, &chasing)) == NULL)
    return;

  if ((ms_target = find_channel_link(who, chptr)) != NULL)
  {
    /* half ops cannot kick other halfops, chanops or owners */
    if (has_member_flags(ms, CHFL_HALFOP) && !has_member_flags(ms, CHFL_CHANOP))
    {
      if ((has_member_flags(ms_target, CHFL_CHANOP|CHFL_HALFOP|CHFL_CHANOWNER)))
      {
        sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                   me.name, source_p->name, name);
        return;
      }
    }
   /* jdc
    * - In the case of a server kicking a user (i.e. CLEARCHAN),
    *   the kick should show up as coming from the server which did
    *   the kick.
    * - Personally, flame and I believe that server kicks shouldn't
    *   be sent anyways.  Just waiting for some oper to abuse it...
    */
    if (IsServer(source_p))
      sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
                           source_p->name, name, who->name, comment);
    else
      sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s KICK %s %s :%s",
                           source_p->name, source_p->username,
                           GET_CLIENT_HOST(source_p), name, who->name, comment);

    sendto_server(client_p, NULL, chptr, CAP_TS6, NOCAPS, NOFLAGS,
                  ":%s KICK %s %s :%s",
                  ID(source_p), chptr->chname, ID(who), comment);
    sendto_server(client_p, NULL, chptr, NOCAPS, CAP_TS6, NOFLAGS,
                  ":%s KICK %s %s :%s", source_p->name, chptr->chname,
                  who->name, comment);

    remove_user_from_channel(ms_target);
  }
  else
    sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
               from, to, user, name);
}
Example #24
0
static int
mo_testline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    struct ConfItem *aconf;
    struct ConfItem *resv_p;
    struct rb_sockaddr_storage ip;
    char user_trunc[USERLEN + 1], notildeuser_trunc[USERLEN + 1];
    const char *name = NULL;
    const char *username = NULL;
    const char *host = NULL;
    char *mask;
    char *p;
    int host_mask;
    int type;
    int duration;
    char *puser, *phost, *reason, *operreason;
    char reasonbuf[BUFSIZE];

    mask = LOCAL_COPY(parv[1]);

    if (IsChannelName(mask)) {
        resv_p = hash_find_resv(mask);
        if (resv_p != NULL) {
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       resv_p->hold ? 'q' : 'Q',
                       resv_p->hold ? (long) ((resv_p->hold - rb_current_time()) / 60) : 0L,
                       resv_p->host, resv_p->passwd);
            /* this is a false positive, so make sure it isn't counted in stats q
             * --nenolod
             */
            resv_p->port--;
        } else
            sendto_one(source_p, form_str(RPL_NOTESTLINE),
                       me.name, source_p->name, parv[1]);
        return 0;
    }

    if((p = strchr(mask, '!'))) {
        *p++ = '\0';
        name = mask;
        mask = p;

        if(EmptyString(mask))
            return 0;
    }

    if((p = strchr(mask, '@'))) {
        *p++ = '\0';
        username = mask;
        host = p;

        if(EmptyString(host))
            return 0;
    } else
        host = mask;

    /* parses as an IP, check for a dline */
    if((type = parse_netmask(host, (struct sockaddr *)&ip, &host_mask)) != HM_HOST) {
#ifdef RB_IPV6
        if(type == HM_IPV6)
            aconf = find_dline((struct sockaddr *)&ip, AF_INET6);
        else
#endif
            aconf = find_dline((struct sockaddr *)&ip, AF_INET);

        if(aconf && aconf->status & CONF_DLINE) {
            get_printable_kline(source_p, aconf, &phost, &reason, &puser, &operreason);
            rb_snprintf(reasonbuf, sizeof(reasonbuf), "%s%s%s", reason,
                        operreason ? "|" : "", operreason ? operreason : "");
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'd' : 'D',
                       (aconf->flags & CONF_FLAGS_TEMPORARY) ?
                       (long) ((aconf->hold - rb_current_time()) / 60) : 0L,
                       phost, reasonbuf);

            return 0;
        }
        /* Otherwise, aconf is an exempt{} */
        if(aconf == NULL &&
           (duration = is_reject_ip((struct sockaddr *)&ip)))
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       '!',
                       duration / 60,
                       host, "Reject cache");
        if(aconf == NULL &&
           (duration = is_throttle_ip((struct sockaddr *)&ip)))
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       '!',
                       duration / 60,
                       host, "Throttled");
    }

    if (username != NULL) {
        rb_strlcpy(user_trunc, username, sizeof user_trunc);
        rb_strlcpy(notildeuser_trunc, *username == '~' ? username + 1 : username, sizeof notildeuser_trunc);
    } else {
        rb_strlcpy(user_trunc, "dummy", sizeof user_trunc);
        rb_strlcpy(notildeuser_trunc, "dummy", sizeof notildeuser_trunc);
    }
    /* now look for a matching I/K/G */
    if((aconf = find_address_conf(host, NULL, user_trunc, notildeuser_trunc,
                                  (type != HM_HOST) ? (struct sockaddr *)&ip : NULL,
                                  (type != HM_HOST) ? (
#ifdef RB_IPV6
                                      (type == HM_IPV6) ? AF_INET6 :
#endif
                                      AF_INET) : 0, NULL))) {
        static char buf[HOSTLEN+USERLEN+2];

        if(aconf->status & CONF_KILL) {
            get_printable_kline(source_p, aconf, &phost, &reason, &puser, &operreason);
            rb_snprintf(buf, sizeof(buf), "%[email protected]%s",
                        puser, phost);
            rb_snprintf(reasonbuf, sizeof(reasonbuf), "%s%s%s", reason,
                        operreason ? "|" : "", operreason ? operreason : "");
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'k' : 'K',
                       (aconf->flags & CONF_FLAGS_TEMPORARY) ?
                       (long) ((aconf->hold - rb_current_time()) / 60) : 0L,
                       buf, reasonbuf);
            return 0;
        }
    }

    /* they asked us to check a nick, so hunt for resvs.. */
    if(name && (resv_p = find_nick_resv(name))) {
        sendto_one(source_p, form_str(RPL_TESTLINE),
                   me.name, source_p->name,
                   resv_p->hold ? 'q' : 'Q',
                   resv_p->hold ? (long) ((resv_p->hold - rb_current_time()) / 60) : 0L,
                   resv_p->host, resv_p->passwd);

        /* this is a false positive, so make sure it isn't counted in stats q
         * --nenolod
         */
        resv_p->port--;
        return 0;
    }

    /* no matching resv, we can print the I: if it exists */
    if(aconf && aconf->status & CONF_CLIENT) {
        sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
                           aconf->info.name, EmptyString(aconf->spasswd) ? "<NULL>" : aconf->spasswd,
                           show_iline_prefix(source_p, aconf, aconf->user),
                           aconf->host, aconf->port, aconf->className);
        return 0;
    }

    /* nothing matches.. */
    sendto_one(source_p, form_str(RPL_NOTESTLINE),
               me.name, source_p->name, parv[1]);
    return 0;
}
Example #25
0
/*
 * m_challenge - generate RSA challenge for wouldbe oper
 * parv[0] = sender prefix
 * parv[1] = operator to challenge for, or +response
 *
 */
static void m_challenge( struct Client *client_p, struct Client *source_p,
                        int parc, char *parv[] )
{
  char * challenge;
  dlink_node *ptr;
  struct ConfItem *aconf, *oconf;
  if(!(source_p->user) || !source_p->localClient)
    return;
  
  /* if theyre an oper, reprint oper motd and ignore */
  if(IsOper(source_p))
  {
    sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, parv[0]);
    SendMessageFile(source_p, &ConfigFileEntry.opermotd);
    return;
  }

  if (*parv[1] == '+')
  {
    /* Ignore it if we aren't expecting this... -A1kmm */
    if (!source_p->user->response)
      return;
     
    if (irccmp(source_p->user->response, ++parv[1]))
    {
      sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), 
                 me.name, source_p->name);
      log_foper(source_p, source_p->user->auth_oper);

      if(ConfigFileEntry.failed_oper_notice)
        sendto_realops_flags(UMODE_ALL, L_ALL,
                             "Failed OPER attempt by %s (%[email protected]%s)",
                             source_p->name, source_p->username, source_p->host);
      return;
    }
     
    if ((aconf = find_conf_by_name(source_p->user->auth_oper, CONF_OPERATOR)) == NULL)
    {
      sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, parv[0]);
      log_foper(source_p, source_p->user->auth_oper);

      if(ConfigFileEntry.failed_oper_notice)
        sendto_realops_flags(UMODE_ALL, L_ALL,
                             "Failed CHALLENGE attempt - host mismatch by %s (%[email protected]%s)",
                             source_p->name, source_p->username, source_p->host);
      return;
    }

    ptr = source_p->localClient->confs.head;
    oconf = ptr->data;
    detach_conf(source_p,oconf);

    if(attach_conf(source_p, aconf) != 0)
    {
      sendto_one(source_p,":%s NOTICE %s :Can't attach conf!",
                 me.name,source_p->name);
      sendto_realops_flags(UMODE_ALL, L_ALL,
                           "Failed CHALLENGE attempt by %s (%[email protected]%s) can't attach conf!",
	                   source_p->name, source_p->username, source_p->host);
      log_foper(source_p, source_p->user->auth_oper);

      attach_conf(source_p, oconf);
      return;
    }
     
    oper_up(source_p, aconf);

    ilog(L_TRACE, "OPER %s by %s!%[email protected]%s",
         source_p->user->auth_oper, source_p->name, source_p->username,
         source_p->host);
    log_oper(source_p, source_p->user->auth_oper);

    MyFree(source_p->user->response);
    MyFree(source_p->user->auth_oper);
    source_p->user->response = NULL;
    source_p->user->auth_oper = NULL;
    return;
  }
  
  MyFree(source_p->user->response);
  MyFree(source_p->user->auth_oper);
  source_p->user->response = NULL;
  source_p->user->auth_oper = NULL;

  if (!(aconf = find_conf_exact(parv[1], source_p->username, source_p->host,
	             		CONF_OPERATOR)) &&
  	!(aconf = find_conf_exact(parv[1], source_p->username,
                                source_p->localClient->sockhost,
                                CONF_OPERATOR)))
  {
    sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, parv[0]);
    log_foper(source_p, source_p->user->auth_oper);

    if(ConfigFileEntry.failed_oper_notice)
      sendto_realops_flags(UMODE_ALL, L_ALL,
                           "Failed CHALLENGE attempt - host mismatch by %s (%[email protected]%s)",
                           source_p->name, source_p->username, source_p->host);
    return;
  }

  if(!aconf->rsa_public_key)
  {
    sendto_one(source_p, ":%s NOTICE %s :I'm sorry, PK authentication "
               "is not enabled for your oper{} block.", me.name, parv[0]);
    return;
  }

  if(!generate_challenge(&challenge, &(source_p->user->response), aconf->rsa_public_key))
  {
    sendto_one(source_p, form_str(RPL_RSACHALLENGE), 
               me.name, parv[0], challenge);
  }

  DupString(source_p->user->auth_oper, aconf->name);
  MyFree(challenge);
  return;
}
Example #26
0
int
m_info(aClient *cptr, aClient *sptr, int parc, char *parv[])

{
  char **text = infotext;
  static time_t last_used=0L;
  Info *infoptr;

  if(IsServer(sptr))
    return 0;
  if (hunt_server(cptr,sptr,":%s INFO :%s",1,parc,parv) == HUNTED_ISME)
  {
    sendto_realops_flags(FLAGS_SPY, "info requested by %s (%[email protected]%s) [%s]",
      sptr->name, sptr->username, sptr->host,
      sptr->user->server);

    if (!IsAnOper(sptr))
    {
      /* reject non local requests */
      if (!MyConnect(sptr))
        return 0;
      if ((last_used + PACE_WAIT) > CurrentTime)
      {
        /* safe enough to give this on a local connect only */
        sendto_one(sptr,form_str(RPL_LOAD2HI),me.name,parv[0]);
        return 0;
      }
      else
        last_used = CurrentTime;
    } /* if (!IsAnOper(sptr)) */

    while (*text)
      sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], *text++);

    /*
     * Now send them a list of all our configuration options
     * (mostly from config.h)
     */
    if (IsAnOper(sptr))
    {
      sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], "Compile-time configuration options:");

      for (infoptr = MyInformation; infoptr->name; infoptr++)
      {
        if (infoptr->intvalue)
          sendto_one(sptr,
            ":%s %d %s :%-30s %-5d [%-30s]",
            me.name,
            RPL_INFO,
            parv[0],
            infoptr->name,
            infoptr->intvalue,
            infoptr->desc);
        else
          sendto_one(sptr,
            ":%s %d %s :%-30s %-5s [%-30s]",
            me.name,
            RPL_INFO,
            parv[0],
            infoptr->name,
            infoptr->strvalue,
            infoptr->desc);
      }

      sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], "");

#ifndef SERVERHIDE
      sendto_one(sptr,
        ":%s %d %s :Compiled on [%s]",
        me.name,
        RPL_INFO,
        parv[0],
        platform);
#endif
      sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], "");

    } /* if (IsAnOper(sptr)) */

    sendto_one(sptr,
      ":%s %d %s :Birth Date: %s, compile #%s",
      me.name,
      RPL_INFO,
      parv[0],
      creation,
      generation);

    sendto_one(sptr,
      ":%s %d %s :On-line since %s",
      me.name,
      RPL_INFO,
      parv[0],
      myctime(me.firsttime));

    sendto_one(sptr, form_str(RPL_ENDOFINFO), me.name, parv[0]);
  } /* if (hunt_server(cptr,sptr,":%s INFO :%s",1,parc,parv) == HUNTED_ISME) */

  return 0;
} /* m_info() */
Example #27
0
/*
** m_okick
**      parv[1] = channel
**      parv[2] = client to kick
**      parv[3] = kick comment
*/
static int
mo_okick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Client *who;
	struct Client *target_p;
	struct Channel *chptr;
	struct membership *msptr;
	int chasing = 0;
	char *comment;
	char *name;
	char *p = NULL;
	char *user;
	char text[10];
	static char buf[BUFSIZE];

	if(*parv[2] == '\0')
	{
		sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "KICK");
		return 0;
	}

	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	comment = (EmptyString(LOCAL_COPY(parv[3]))) ? LOCAL_COPY(parv[2]) : LOCAL_COPY(parv[3]);
	if(strlen(comment) > (size_t) TOPICLEN)
		comment[TOPICLEN] = '\0';

	*buf = '\0';
	if((p = strchr(parv[1], ',')))
		*p = '\0';

	name = LOCAL_COPY(parv[1]);

	chptr = find_channel(name);
	if(!chptr)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name);
		return 0;
	}


	if((p = strchr(parv[2], ',')))
		*p = '\0';
	user = LOCAL_COPY(parv[2]);	// strtoken(&p2, parv[2], ","); 
	if(!(who = find_chasing(source_p, user, &chasing)))
	{
		return 0;
	}

	if((target_p = find_client(user)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, user);
		return 0;
	}

	if((msptr = find_channel_membership(chptr, target_p)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
			   me.name, source_p->name, parv[1], parv[2]);
		return 0;
	}

	sendto_realops_snomask(SNO_GENERAL, L_ALL,
			       "OKICK called for %s %s by %s!%[email protected]%s",
			       chptr->chname, target_p->name,
			       source_p->name, source_p->username, source_p->host);
	ilog(L_MAIN, "OKICK called for %s %s by %s",
	     chptr->chname, target_p->name,
	     get_oper_name(source_p));

	sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
			     me.name, chptr->chname, who->name, comment);
	sendto_server(&me, chptr, CAP_TS6, NOCAPS,
		      ":%s KICK %s %s :%s", me.id, chptr->chname, who->id, comment);
	remove_user_from_channel(msptr);

	rb_snprintf(text, sizeof(text), "K%s", who->id);

	/* we don't need to track NOREJOIN stuff unless it's our client being kicked */
	if(MyClient(who) && chptr->mode.mode & MODE_NOREJOIN)
		channel_metadata_time_add(chptr, text, rb_current_time(), "KICKNOREJOIN");
	return 0;
}
Example #28
0
/*
** mo_forcenick
**      parv[1] = forcenick victim
**      parv[2] = new nickname 
*/
static int
mo_forcenick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Client *target_p, *exist_p;
	const char *user;
	const char *newnick;

	user = parv[1];

	/* You must be this tall to ride the ride */
	if(!IsOperLocalForce(source_p))
	{
		sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "local_force");
		return 0;
	}

	/* Truncate it so clean_nick doesn't spaz out */
	if(!EmptyString(parv[2]))
	{
		char *s;
		s = LOCAL_COPY(parv[2]);
		if(strlen(s) > (size_t) NICKLEN)
			s[NICKLEN] = '\0';
		newnick = s;
	}
	else
	{
		sendto_one_numeric(source_p, ERR_NONICKNAMEGIVEN, form_str(ERR_NONICKNAMEGIVEN),
				   me.name, source_p->name);
		return 0;
	}

	/* Nick has to be clean or we'll have a protocol violation... */
	if(!clean_nick(newnick))
	{
		sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), 
			   me.name, user, newnick);
		return 0;
	}

	/* Find the target... */
	if((target_p = find_named_person(user)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "FORCENICK");
		return 0;
	}

	/* If it's a server, sod it, changing its name is stupid... */
	if(IsServer(target_p) || IsMe(target_p))
	{
		sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), user);
		return 0;
	}

	/* Do we have permission to send it globally? */
	if(!MyClient(target_p) && (!IsOperGlobalForce(source_p)))
	{
		sendto_one_notice(source_p, ":Nick %s is not on your server and you do not have the global_force flag",
				  target_p->name);
		return 0;
	}

	/* Check to see if the new nick exists */
	if((exist_p = find_named_person(newnick)) != NULL)
	{
		/* Could just be a case shift */
		if(irccmp(target_p->name, newnick))
		{
			sendto_one(source_p, form_str(ERR_NICKNAMEINUSE),
				   me.name, user, newnick);
			return 0;
		}
		/* If it's the same nick, fuck it */
		else if(!strcmp(target_p->name, newnick))
			return 0;
	}

	sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
			       "Received FORCENICK message for %s!%[email protected]%s. From %s (Newnick: %s)",
			       target_p->name, target_p->username, target_p->orighost, 
			       source_p->name, newnick);
	ilog(L_MAIN, "FORCENICK called for [%s] by %s!%[email protected]%s",
	     target_p->name, source_p->name, source_p->username, source_p->host);

	sendto_one_notice(target_p, ":You have been forcenicked from %s to %s by %s",
			  target_p->name, newnick, source_p->name);

	if(!MyClient(target_p))
	{
		struct Client *cptr = target_p->servptr;
		sendto_one(cptr, ":%s ENCAP %s FORCENICK %s :%s",
				 get_id(source_p, cptr), cptr->name, get_id(target_p, cptr), newnick);
		return 0;
	}

	change_nick(target_p, newnick);

	return 0;
}
Example #29
0
/*
** m_ltrace - LimitedTRACE... like m_trace() but doesn't return TRACEUSER, TRACEUNKNOWN, or TRACECLASS
**      parv[0] = sender prefix
**      parv[1] = servername
*/
int     m_ltrace(struct Client *cptr,
                struct Client *sptr,
                int parc,
                char *parv[])
{
  int   i;
  struct Client       *acptr = NULL;
  char  *tname;
  int   doall, link_s[MAXCONNECTIONS], link_u[MAXCONNECTIONS];
  int   cnt = 0, wilds, dow;
  static time_t now;
  
  if (check_registered(sptr))
    return 0;

#ifdef SERVERHIDE
  if (!IsAnOper(sptr))
    return 0;
#endif

  if (parc > 2)
    if (hunt_server(cptr, sptr, ":%s LTRACE %s :%s",
                    2, parc, parv))
      return 0;
  
  if (parc > 1)
    tname = parv[1];
  else
    tname = me.name;

  switch (hunt_server(cptr, sptr, ":%s LTRACE :%s", 1, parc, parv))
    {
    case HUNTED_PASS: /* note: gets here only if parv[1] exists */
      {
        struct Client *ac2ptr;
        
        ac2ptr = next_client(GlobalClientList, tname);
        if (ac2ptr)
          sendto_one(sptr, form_str(RPL_TRACELINK), me.name, parv[0],
                     ircd_version, debugmode, tname, ac2ptr->from->name);
        else
          sendto_one(sptr, form_str(RPL_TRACELINK), me.name, parv[0],
                     ircd_version, debugmode, tname, "ac2ptr_is_NULL!!");
        return 0;
      }
    case HUNTED_ISME:
      break;
    default:
      return 0;
    }


  if(MyClient(sptr))
    sendto_realops_flags(FLAGS_SPY, "ltrace requested by %s (%[email protected]%s) [%s]",
                       sptr->name, sptr->username, sptr->host,
                       sptr->user->server);


  doall = (parv[1] && (parc > 1)) ? match(tname, me.name): TRUE;
  wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
  dow = wilds || doall;

  if(!IsAnOper(sptr) || !dow) /* non-oper traces must be full nicks */
                              /* lets also do this for opers tracing nicks */
    { 
      const char* name;
      const char* ip;
      int         c_class;

      acptr = hash_find_client(tname,(struct Client *)NULL);
      if(!acptr || !IsPerson(acptr))
        { 
          /* this should only be reached if the matching
             target is this server */
          sendto_one(sptr, form_str(RPL_ENDOFTRACE),me.name,
                     parv[0], tname);
          return 0;
        }
      name = get_client_name(acptr, FALSE);
      ip = inetntoa((char*) &acptr->ip);

      c_class = get_client_class(acptr);

      if (IsAnOper(acptr))
        { 
          sendto_one(sptr, form_str(RPL_TRACEOPERATOR),
                     me.name, parv[0], c_class,
                     name,
                     IsAnOper(sptr)?ip:(IsIPHidden(acptr)?"255.255.255.255":ip),
                     now - acptr->lasttime,
                     (acptr->user)?(now - acptr->user->last):0);
        }
      sendto_one(sptr, form_str(RPL_ENDOFTRACE),me.name,
                 parv[0], tname);
      return 0;
    }
  
  for (i = 0; i < MAXCONNECTIONS; i++)
    link_s[i] = 0, link_u[i] = 0;
                        
  if (dow && LIFESUX && !IsOper(sptr))
    {
      sendto_one(sptr,form_str(RPL_LOAD2HI),me.name,parv[0]);
      return 0;
    }

  /*
   * Count up all the servers and clients in a downlink.
   */
  if (doall) {
    for (acptr = GlobalClientList; acptr; acptr = acptr->next) {
      if (IsServer(acptr)) 
        ++link_s[acptr->from->fd];
    }
  }

  /* report all direct connections */
  now = time(NULL);
  for (i = 0; i <= highest_fd; i++)
    {
      const char* name;
      const char* ip;
      int         c_class;
      
      if (!(acptr = local[i])) /* Local Connection? */
        continue;
      if (IsInvisible(acptr) && dow &&
          !(MyConnect(sptr) && IsAnOper(sptr)) &&
          !IsAnOper(acptr) && (acptr != sptr))
        continue;
      if (!doall && wilds && !match(tname, acptr->name))
        continue;
      if (!dow && irccmp(tname, acptr->name))
        continue;
      name = get_client_name(acptr, FALSE);
      ip = inetntoa((const char*) &acptr->ip);

      c_class = get_client_class(acptr);
      
      switch(acptr->status)
        {
        case STAT_HANDSHAKE:
#ifdef HIDE_SERVERS_IPS
	  name=get_client_name(acptr, MASK_IP);
#endif	  
          sendto_one(sptr, form_str(RPL_TRACEHANDSHAKE), me.name,
                     parv[0], c_class, name);
          cnt++;
          break;
	case STAT_CONNECTING:
#ifdef HIDE_SERVERS_IPS
          name=get_client_name(acptr, MASK_IP);
#endif
	  sendto_one(sptr, form_str(RPL_TRACECONNECTING), me.name, 
	             parv[0], c_class, name);
	  cnt++;
	  break;
        case STAT_ME:
          break;
        case STAT_CLIENT:
          /* Well, most servers don't have a LOT of OPERs... let's show them too */
          if ((IsAnOper(sptr) &&
              (MyClient(sptr) || !(dow && IsInvisible(acptr))))
              || !dow || IsAnOper(acptr))
            {
              if (IsAnOper(acptr))
                sendto_one(sptr,
                           form_str(RPL_TRACEOPERATOR),
                           me.name, parv[0], c_class,
                           name, 
                           IsAnOper(sptr)?ip:(IsIPHidden(acptr)?"255.255.255.255":ip), 
                           now - acptr->lasttime,
                           (acptr->user)?(now - acptr->user->last):0);
              cnt++;
            }
          break;
        case STAT_SERVER:
#if 0
          if (acptr->serv->user)
            sendto_one(sptr, form_str(RPL_TRACESERVER),
                       me.name, parv[0], c_class, link_s[i],
                       link_u[i], name, acptr->serv->by,
                       acptr->serv->user->username,
                       acptr->serv->user->host, now - acptr->lasttime);
          else
#endif
#ifdef HIDE_SERVERS_IPS
	    name=get_client_name(acptr, MASK_IP);
#endif	    
            sendto_one(sptr, form_str(RPL_TRACESERVER),
                       me.name, parv[0], c_class, link_s[i],
                       link_u[i], name, *(acptr->serv->by) ?
                       acptr->serv->by : "*", "*",
                       me.name, now - acptr->lasttime);
          cnt++;
          break;
        default: /* ...we actually shouldn't come here... --msa */
          sendto_one(sptr, form_str(RPL_TRACENEWTYPE), me.name,
                     parv[0], name);
          cnt++;
          break;
        }
    }
  /*
   * Add these lines to summarize the above which can get rather long
   * and messy when done remotely - Avalon
   */
  if (!IsAnOper(sptr) || !cnt)
    {
      if (cnt)
          return 0;
      /* let the user have some idea that its at the end of the
       * trace
       */
      sendto_one(sptr, form_str(RPL_TRACESERVER),
                 me.name, parv[0], 0, link_s[me.fd],
                 link_u[me.fd], me.name, "*", "*", me.name);
      sendto_one(sptr, form_str(RPL_ENDOFTRACE),me.name,
                 parv[0],tname);
      return 0;
    }
  sendto_one(sptr, form_str(RPL_ENDOFTRACE),me.name, parv[0],tname);
  return 0;
}
Example #30
0
/*
** mo_ojoin
**      parv[1] = channel
*/
static int
mo_ojoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr;
	int move_me = 0;

	/* admins only */
	if(!IsOperAdmin(source_p))
	{
		sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin");
		return 0;
	}

	if(*parv[1] == '@' || *parv[1] == '%' || *parv[1] == '+' || *parv[1] == '&' || *parv[1] == '~')
	{
		parv[1]++;
		move_me = 1;
	}

	if((chptr = find_channel(parv[1])) == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	if(IsMember(source_p, chptr))
	{
		sendto_one_notice(source_p, ":Please part %s before using OJOIN", parv[1]);
		return 0;
	}

	if(move_me == 1)
		parv[1]--;

	sendto_wallops_flags(UMODE_WALLOP, &me,
			     "OJOIN called for %s by %s!%[email protected]%s",
			     parv[1], source_p->name, source_p->username, source_p->host);
	ilog(L_MAIN, "OJOIN called for %s by %s",
	     parv[1], get_oper_name(source_p));
	/* only sends stuff for #channels remotely */
	sendto_server(NULL, chptr, NOCAPS, NOCAPS,
			":%s WALLOPS :OJOIN called for %s by %s!%[email protected]%s",
			me.name, parv[1],
			source_p->name, source_p->username, source_p->host);

        if(*parv[1] == '~' && ConfigChannel.use_owner)
        {
                add_user_to_channel(chptr, source_p, CHFL_OWNER);
                sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
                                ":%s SJOIN %ld %s + :~%s",
                                me.id, (long) chptr->channelts, chptr->chname, source_p->id);
                sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
                                source_p->name,
                                source_p->username, source_p->host, chptr->chname);
                sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +q %s",
                                me.name, chptr->chname, source_p->name);
        }
        else if(*parv[1] == '&' && ConfigChannel.use_admin)
	{
		add_user_to_channel(chptr, source_p, CHFL_ADMIN);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :!%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +a %s",
				     me.name, chptr->chname, source_p->name);

	}
	else if(*parv[1] == '@')
	{
		add_user_to_channel(chptr, source_p, CHFL_CHANOP);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :@%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
				     me.name, chptr->chname, source_p->name);

	}
	else if(*parv[1] == '%' && ConfigChannel.use_halfop)
	{
		add_user_to_channel(chptr, source_p, CHFL_HALFOP);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :%s%s",
			      me.id, (long) chptr->channelts, chptr->chname, "%", source_p->id);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +h %s",
				     me.name, chptr->chname, source_p->name);
	}
	else if(*parv[1] == '+')
	{
		add_user_to_channel(chptr, source_p, CHFL_VOICE);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s SJOIN %ld %s + :+%s",
			      me.id, (long) chptr->channelts, chptr->chname, source_p->id);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s",
				     me.name, chptr->chname, source_p->name);
	}
	else
	{
		add_user_to_channel(chptr, source_p, CHFL_PEON);
		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
			      ":%s JOIN %ld %s +",
			      source_p->id, (long) chptr->channelts, chptr->chname);
		sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%[email protected]%s JOIN %s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname);
	}

	/* send the topic... */
	if(chptr->topic != NULL)
	{
		sendto_one(source_p, form_str(RPL_TOPIC), me.name,
			   source_p->name, chptr->chname, chptr->topic);
		sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name,
			   source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time);
	}

	source_p->localClient->last_join_time = rb_current_time();
	channel_member_names(chptr, source_p, 1);

	return 0;
}