コード例 #1
0
ファイル: f_ulinessl.c プロジェクト: wirelesspt/unreal
// Parts all insecure users on a +z channel (NOT KICK)
void f_part_insecure_users (aChannel *chptr)
{
	Member *member, *mb2;
	aClient *cptr;
	char *comment = "Insecure user not allowed on secure channel (+z)";
	for (member = chptr->members; member; member = mb2)
	{
		mb2 = member->next;
		cptr = member->cptr;
		if (MyClient(cptr) && !IsSecureConnect(cptr) && !IsULine(cptr))
		{
			RunHook4(HOOKTYPE_LOCAL_PART, cptr, &me, chptr, comment);
			if ((chptr->mode.mode & MODE_AUDITORIUM) && is_chanownprotop(cptr, chptr))
			{
				sendto_chanops_butone(cptr, chptr, ":%s!%s@%s PART %s :%s",
					cptr->name, cptr->user->username, GetHost(cptr), chptr->chname, comment);
				sendto_prefix_one(cptr, &me, ":%s!%s@%s PART %s :%s",
					cptr->name, cptr->user->username, GetHost(cptr), chptr->chname, comment);
			} 
			else
			{
				sendto_channel_butserv(chptr, &me, ":%s!%s@%s PART %s :%s",
					cptr->name, cptr->user->username, GetHost(cptr), chptr->chname, comment);
			}
			sendto_one(cptr, err_str(ERR_SECUREONLYCHAN), me.name, cptr->name, chptr->chname);
			sendto_serv_butone_token(&me, cptr->name, MSG_PART, TOK_PART, "%s :%s", chptr->chname, comment);
			remove_user_from_channel(cptr, chptr);
		}
	}
}
コード例 #2
0
ファイル: secureonly.c プロジェクト: RanadeepPolavarapu/IRCd
/** Kicks all insecure users on a +z channel */
static void secureonly_kick_insecure_users(aChannel *chptr)
{
	Member *member, *mb2;
	aClient *cptr;
	int i = 0;
	Hook *h;
	char *comment = "Insecure user not allowed on secure channel (+z)";

	if (!IsSecureOnly(chptr))
		return;

	for (member = chptr->members; member; member = mb2)
	{
		mb2 = member->next;
		cptr = member->cptr;
		if (MyClient(cptr) && !IsSecureConnect(cptr) && !IsULine(cptr))
		{
			RunHook5(HOOKTYPE_LOCAL_KICK, &me, &me, cptr, chptr, comment);

			i = 0;
			for (h = Hooks[HOOKTYPE_VISIBLE_IN_CHANNEL]; h; h = h->next)
			{
				i = (*(h->func.intfunc))(cptr,chptr);
				if (i != 0)
					break;
			}

			if (i != 0 && !(is_skochanop(cptr, chptr) || has_voice(cptr,chptr)))
			{
				sendto_chanops_butone(cptr, chptr, ":%s KICK %s %s :%s", me.name, chptr->chname, cptr->name, comment);
				sendto_prefix_one(cptr, &me, ":%s KICK %s %s :%s", me.name, chptr->chname, cptr->name, comment);
			}
			else
			{
				sendto_channel_butserv(chptr, &me, ":%s KICK %s %s :%s", me.name, chptr->chname, cptr->name, comment);
			}

			sendto_server(&me, 0, 0, ":%s KICK %s %s :%s", me.name, chptr->chname, cptr->name, comment);

			remove_user_from_channel(cptr, chptr);
		}
	}
}
コード例 #3
0
int
m_scan_idle(struct Client *cptr, struct Client *sptr, int parc, char *parv[], char *varparv[])
{
	struct Client *ptr, *target = NULL;
	char *eptr, buffer[321];
	int idle_time, check_time, len = 0, count = 0;

	if(MyClient(sptr) && !HasUmode(sptr, UMODE_USER_AUSPEX))
	{
		if(SeesOperMessages(sptr))
			sendto_one(sptr,":%s NOTICE %s :You have no a umode", me.name, parv[0]);
		else
			sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
		return 0;
	}

	if(parc < 3)
	{
		if (!IsServer(sptr))
			sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
					me.name, parv[0], "SCAN IDLE");
		return 0;
	}

	idle_time = strtoul(parv[2], &eptr, 10);
	if(eptr == parv[2])
		return 0;
	/* Store the timestamp which last_sent should be >= to save time */
	check_time = CurrentTime - idle_time;

	/* If the query is for another server, pass it on and return. */
	if(parc > 3)
	{
		if(MyClient(sptr) && !HasUmode(sptr, UMODE_REMOTEINFO))
		{
			if(SeesOperMessages(sptr))
				sendto_one(sptr,":%s NOTICE %s :You have no S umode(cannot send remote)", me.name, parv[0]);
			else
				sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
			return 0;
		}

		if(!irccmp(parv[3], "GLOBAL") || !irccmp(parv[3], "*"))
			sendto_serv_butone(cptr, ":%s SCAN IDLE %d *", parv[0], idle_time);
		else if((target = find_server(parv[3])) == NULL) {
			sendto_one(sptr, form_str(ERR_NOSUCHSERVER),
					me.name, parv[0], parv[3]);
			return 0;
		}else if(!IsMe(target)) { /* But only if the query is not on us... */

			sendto_prefix_one(target, sptr, ":%s SCAN IDLE %d %s", parv[0],
					idle_time, target->name);
			return 0;
		}
	}

	buffer[0] = '\0';
	for(ptr = local_cptr_list; ptr; ptr = ptr->next_local_client)
	{
		if(ptr->user->last_sent < check_time)
			continue;

		if(len + strlen(ptr->name) > 319)
		{
			buffer[len - 1] = '\0'; /* Strip the trailing space */
			send_markup(sptr, &me, "SCAN-IDLE", "%d %s", idle_time, buffer);
			buffer[0] = '\0';
			len = 0;
		}

		strcat(buffer, ptr->name);
		strcat(buffer, " ");
		len += strlen(ptr->name) + 1;
		count++;
	}

	if(buffer[0])
	{
		buffer[len - 1] = '\0';
		send_markup(sptr, &me, "SCAN-IDLE", "%d %s", idle_time, buffer);
	}

	send_markup(sptr, &me, "IDLE-END", "End of idle listing");
	if(count > 0 || target || parc == 3) /* Don't give a summary for globals if no results matched */
		send_markup(sptr, &me, "SCAN-SUMMARY", "%d matched", count);

	return 0;
}
コード例 #4
0
ファイル: s_numeric.c プロジェクト: Apsu/bahamut
/*
 * * DoNumeric (replacement for the old do_numeric) *
 * 
 * parc         number of arguments ('sender' counted as one!)
 * parv[0]      pointer to 'sender' (may point to empty string)
 * parv[1]..parv[parc-1] 
 *              pointers to additional parameters, this is a NULL 
 *              terminated list (parv[parc] == NULL).
 * 
 * *WARNING* 
 * Numerics are mostly error reports. If there is something 
 * wrong with the message, just *DROP* it! Don't even think of 
 * sending back a neat error message -- big danger of creating 
 * a ping pong error message...
 */
int do_numeric(int numeric, aClient *cptr, aClient *sptr, int parc, 
	       char *parv[])
{
    aClient    *acptr;
    aChannel   *chptr;
    char       *nick, *p;
    int         i;

    if (parc < 1 || !IsServer(sptr))
	return 0;
    /* Remap low number numerics. */
    if (numeric < 100)
	numeric += 100;
    /*
     * Prepare the parameter portion of the message into 'buffer'. 
     * (Because the buffer is twice as large as the message buffer for
     * the socket, no overflow can occur here... ...on current
     * assumptions--bets are off, if these are changed --msa) 
     * Note: if buffer is non-empty, it will begin with SPACE.
     */
    buffer[0] = '\0';
    if (parc > 1)
    {
	int bpos = 0;
	char *p;

	for (i = 2; i < (parc - 1); i++)
	{
	    buffer[bpos++] = ' ';
	    for(p = parv[i]; *p; p++)
		buffer[bpos++] = *p;
	}
	buffer[bpos++] = ' ';
	buffer[bpos++] = ':';
	for(p = parv[parc - 1]; *p; p++)
	    buffer[bpos++] = *p;
	buffer[bpos] = '\0';
    }
    for (; (nick = strtoken(&p, parv[1], ",")); parv[1] = NULL)
    {
	if ((acptr = find_client(nick, (aClient *) NULL)))
	{
	    int dohide;

	    /*
	     * Drop to bit bucket if for me... ...one might consider
	     * sendto_ops * here... --msa * And so it was done. -avalon *
	     * And regretted. Dont do it that way. Make sure * it goes
	     * only to non-servers. -avalon * Check added to make sure
	     * servers don't try to loop * with numerics which can happen
	     * with nick collisions. * - Avalon
	     */

#ifdef HIDE_NUMERIC_SOURCE
	    dohide = MyClient(acptr) ? 1 : 0;
#else
	    dohide = 0;
#endif

	    if (!IsMe(acptr) && IsPerson(acptr))
		sendto_prefix_one(acptr, dohide ? &me : sptr, ":%s %d %s%s",
				  dohide ? me.name : parv[0], numeric, nick, buffer);
	    else if (IsServer(acptr) && acptr->from != cptr)
		sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
				  parv[0], numeric, nick, buffer);
	}
	else if ((chptr = find_channel(nick, (aChannel *) NULL)))
	{
	    int dohide;

#ifdef HIDE_NUMERIC_SOURCE
	    dohide = 1;
#else
	    dohide = 0;
#endif
	    sendto_channel_butserv(chptr, dohide ? &me : sptr, ":%s %d %s%s",
				   dohide ? me.name : parv[0], numeric, 
				   chptr->chname, buffer);

	    sendto_channel_remote_butone(cptr, sptr, chptr, 
					 parv[0], numeric, 
					 chptr->chname, buffer);

	}
    }
    return 0;
}
コード例 #5
0
static  int     m_message(struct Client *cptr,
                          struct Client *sptr,
                          int parc,
                          char *parv[],
                          int notice)
{
  struct Client       *acptr;
#ifdef NEED_TLD_FOR_MASS_NOTICE
  char  *s;
#endif
  struct Channel *chptr;
  char  *nick, *server, *host;
  char  errbuf[BUFSIZE];
  const char *cmd;
  int type=0, msgs=0;
#ifdef FLUD
  int flud;
#endif

  cmd = notice ? MSG_NOTICE : MSG_PRIVATE;

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

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

  if (MyConnect(sptr))
    {
#ifdef ANTI_SPAMBOT
#ifndef ANTI_SPAMBOT_WARN_ONLY
      /* if its a spambot, just ignore it */
      if(sptr->join_leave_count >= MAX_JOIN_LEAVE_COUNT)
        return 0;
#endif
#endif
#ifdef NO_DUPE_MULTI_MESSAGES
      if (strchr(parv[1],','))
        parv[1] = canonize(parv[1]);
#endif
    }


  /*
  ** channels are privmsg'd a lot more than other clients, moved up here
  ** plain old channel msg ?
  */
  while(msgs < MAX_MULTI_MESSAGES)
  {
     if(!msgs)
        nick = strtok(parv[1], ",");
     else
        nick = strtok(NULL, ",");

     if(!nick && msgs == 0)
        nick = parv[1];
     else if(!nick)
        break;

  if( IsChanPrefix(*nick)
      && (IsPerson(sptr) && (chptr = hash_find_channel(nick, NullChn))))
    {
#ifdef FLUD
#ifdef DEATHFLUD
      if(!notice && check_for_ctcp(parv[2])
         && check_for_flud(sptr, NULL, chptr, 1))
        return 0;
      if((flud = check_for_spam(sptr, NULL, chptr, parv[2])))
        {
          if (check_for_flud(sptr, NULL, chptr, flud))
            return 0;
        }
#else /* DEATHFLUD */
      if(!notice)
	if(check_for_ctcp(parv[2]))
	  check_for_flud(sptr, NULL, chptr, 1);
#endif /* DEATHFLUD */
#endif /* FLUD */

      /* 
       * Channel color blocking. Usually set with the +c chanmode.
       * - Andre Guibert de Bruet <*****@*****.**>
       */
      if(chptr->mode.mode & MODE_NOCOLOR)
	strip_colour(parv[2]);

      switch (can_send(sptr, chptr))
        {
        case 0:
          sendto_channel_message_butone(cptr, sptr, chptr, cmd, parv[2]);
          break;
        case MODE_QUIETUNIDENT:
          if (!notice)
            sendto_one(sptr, form_str(ERR_QUIETUNIDENT),
                       me.name, parv[0], nick);
          break;
        case MODE_MODERATED:
          if (chptr->mode.mode & MODE_OPMODERATE)
            {
              /* The flag MODE_OPMODERATE will instruct sendto_channel_type()
	       * to put bare #channel in the message (instead of @#channel);
	       * it will still be sent to ops and servers with ops only.
	       * Strange things will happen if the user is not banned
	       * remotely.
	       * -- jilles
	       */
              sendto_channel_type(cptr, sptr, chptr,
			      MODE_CHANOP | MODE_OPMODERATE, nick, cmd,
			      parv[2]);
            }
          else
            {
              if (!notice)
                sendto_one(sptr, form_str(ERR_CANNOTSENDTOCHAN),
                           me.name, parv[0], nick);
            }
          break;
        default:
          break;
        }
      msgs++;
      continue;
    }
      
  /*
  ** @# type of channel msg?
  */

  if(*nick == '@')
    type = MODE_CHANOP;
  else if(*nick == '+')
    type = MODE_CHANOP|MODE_VOICE;

  if(type)
    {
      /* Strip if using DALnet chanop/voice prefix. */
      if (*(nick+1) == '@' || *(nick+1) == '+')
        {
          nick++;
          *nick = '@';
          type = MODE_CHANOP|MODE_VOICE;
        }

      /* suggested by Mortiis */
      if(!*nick)        /* if its a '\0' dump it, there is no recipient */
        {
          sendto_one(sptr, form_str(ERR_NORECIPIENT),
                     me.name, parv[0], cmd);
          return -1;
        }

      if (!IsPerson(sptr))      /* This means, servers can't send messages */
        return -1;

      /* At this point, nick+1 should be a channel name i.e. #foo or &foo
       * if the channel is found, fine, if not report an error
       */

      if ( (chptr = hash_find_channel(nick+1, NullChn)) )
        {
#ifdef FLUD
#ifdef DEATHFLUD
          if(!notice && check_for_ctcp(parv[2])
             && check_for_flud(sptr, NULL, chptr, 1))
            return 0;
          if((flud = check_for_spam(sptr, NULL, chptr, parv[2])))
            {
              if (check_for_flud(sptr, NULL, chptr, flud))
                return 0;
            }
#else /* DEATHFLUD */
          if(!notice)
            if(check_for_ctcp(parv[2]))
              check_for_flud(sptr, NULL, chptr, 1);
#endif /* DEATHFLUD */
#endif /* FLUD */

          if (!is_chan_op(sptr,chptr))
            {
              if (!notice)
                {
                  sendto_one(sptr, form_str(ERR_CANNOTSENDTOCHAN),
                             me.name, parv[0], nick);
                }
	msgs++;
	continue;
            }
          else
            {
              sendto_channel_type(cptr,
                                  sptr,
                                  chptr,
                                  type,
                                  nick+1,
                                  cmd,
                                  parv[2]);
            }
        }
      else
        {
	  if (!IsServer(sptr))
	    sendto_one(sptr, form_str(ERR_NOSUCHNICK),
		       me.name, parv[0], nick);
	  msgs++;
	  continue;
        }
      return 0;
    }

  /*
  ** nickname addressed?
  */
  if ((acptr = find_person(nick, NULL)))
    {
#ifdef FLUD
#ifdef DEATHFLUD
      if(!notice && MyConnect(sptr) && check_for_ctcp(parv[2])
         && check_for_flud(sptr, acptr, NULL, 1))
        return 0;
      if(MyConnect(sptr) && (flud = check_for_spam(sptr, acptr, NULL, parv[2])))
        {
          if (check_for_flud(sptr, acptr, NULL, flud))
            return 0;
        }
#else /* DEATHFLUD */
      if(!notice && MyConnect(sptr))
	if(check_for_ctcp(parv[2]))
	  if(check_for_flud(sptr, acptr, NULL, 1))
	    return 0;
#endif /* DEATHFLUD */
#endif /* FLUD */
#ifdef ANTI_DRONE_FLOOD
      if(MyConnect(acptr) && IsClient(sptr) && !NoFloodProtection(sptr) && DRONETIME)
        {
          if((acptr->first_received_message_time+DRONETIME) < CurrentTime)
            {
              acptr->received_number_of_privmsgs=1;
              acptr->first_received_message_time = CurrentTime;
              acptr->drone_noticed = 0;
            }
          else
            {
              if(acptr->received_number_of_privmsgs > DRONECOUNT)
                {
                  if(acptr->drone_noticed == 0) /* tiny FSM */
                    {
                      sendto_ops_flag(UMODE_BOTS,
				      "Possible Drone Flooder %s [%s@%s] on %s target: %s",
				      sptr->name, sptr->username,
				      sptr->host,
				      sptr->user->server, acptr->name);
                      acptr->drone_noticed = 1;
                    }
                  /* heuristic here, if target has been getting a lot
                   * of privmsgs from clients, and sendq is above halfway up
                   * its allowed sendq, then throw away the privmsg, otherwise
                   * let it through. This adds some protection, yet doesn't
                   * DOS the client.
                   * -Dianora
                   */
                  if(DBufLength(&acptr->sendQ) > (get_sendq(acptr)/2UL))
                    {
                      if(acptr->drone_noticed == 1) /* tiny FSM */
                        {
                          sendto_ops_flag(UMODE_BOTS,
					  "ANTI_DRONE_FLOOD SendQ protection activated for %s",
					  acptr->name);

                          sendto_one(acptr,     
				     ":%s NOTICE %s :*** Notice -- Server drone flood protection activated for %s",
                                     me.name, acptr->name, acptr->name);
                          acptr->drone_noticed = 2;
                        }
                    }

                  if(DBufLength(&acptr->sendQ) <= (get_sendq(acptr)/4UL))
                    {
                      if(acptr->drone_noticed == 2)
                        {
                          sendto_one(acptr,     
                                     ":%s NOTICE %s :*** Notice -- Server drone flood protection de-activated for %s",
                                     me.name, acptr->name, acptr->name);
                          acptr->drone_noticed = 1;
                        }
                    }
                  if(acptr->drone_noticed > 1)
                    return 0;
                }
              else
                acptr->received_number_of_privmsgs++;
            }
        }
#endif

      /*
       * Simple herustic here... If PRIVMSG is locked down via
       * F:noidprivmsg:1, then act like every client is +E.
       * Otherwise, assume the normal behaviour. All in a nice
       * single if statement. --nenolod
       */
      if (MyClient(sptr) && sptr != acptr &&
	   (GlobalSetOptions.noidprivmsg != 0 ||
	   HasUmode(acptr,UMODE_BLOCK_NOTID)) 
	   && !HasUmode(sptr,UMODE_IDENTIFIED)
	   && !sptr->user->servlogin[0]
	   && !HasUmode(acptr,UMODE_DONTBLOCK)
	   && !HasUmode(sptr,UMODE_DONTBLOCK))
        {
	  /* Replace errbuf with either the default or custom message,
	   * then send the numeric on...
	   *    --nenolod
	   */
	  if (GlobalSetOptions.noidprivmsg != 0 &&
		GlobalSetOptions.noidprivmsg_notice[0])
	    {
	      strncpy_irc(errbuf, GlobalSetOptions.noidprivmsg_notice, BUFSIZE);
	    }
	  else
	    {
	      ircsnprintf(errbuf, BUFSIZE, get_str(STR_NOTID_DEFAULT),
		nick);
	    }

          sendto_one(sptr, form_str(ERR_BLOCKING_NOTID),
	      me.name, parv[0], errbuf);
	  return 0;
        }

#ifdef  SILENCE
      /* only check silence masks at the recipient's server -- jilles */
      if (!MyConnect(acptr) || !is_silenced(sptr, acptr)) {
#endif
        if (MyConnect(sptr) && acptr->user && (sptr != acptr))
          {
#ifdef  NCTCP
            /* NCTCP (umode +C) checks  -- PMA */
            if (parv[2][0] == 1) /* is CTCP */
	      /* Huh? No way, NOCTCP means NOCTCP. */
/*               if (!HasUmode(sptr,UMODE_IMMUNE) && */
/*                   !HasUmode(acptr,UMODE_IMMUNE)) */
	      if (HasUmode(acptr,UMODE_NOCTCP) ||            /* block to +C */
		  (notice && HasUmode(sptr,UMODE_NOCTCP)))   /* block replies from +C */
		return 0;                                    /* kill it! */
#endif /* NCTCP */
            if (!notice && acptr->user->away)
              sendto_one(sptr, form_str(RPL_AWAY), me.name,
                         parv[0], acptr->name,
                         acptr->user->away);
          }
        {
          /* here's where we actually send the message */
          int is_ctcp = check_for_ctcp(parv[2]);
          int cap = is_ctcp ? CAP_IDENTIFY_CTCP : CAP_IDENTIFY_MSG;
          sendto_prefix_one(acptr, sptr, ":%s %s %s :%s%s",
                            parv[0], cmd, nick,
                            !(acptr->caps & cap) ? "" :
                            (HasUmode(sptr, UMODE_IDENTIFIED) ? "+" : "-"),
                            parv[2]);
        }
#ifdef SILENCE
      }
#endif

      msgs++;
      continue;
    }

  /* Everything below here should be reserved for opers 
   * as pointed out by Mortiis, user%[email protected] 
   * syntax could be used to flood without FLUD protection
   * its also a delightful way for non-opers to find users who
   * have changed nicks -Dianora
   *
   * Grrr it was pointed out to me that x@service is valid
   * for non-opers too, and wouldn't allow for flooding/stalking
   * -Dianora
   *
   * Valid or not, @servername is unacceptable, it reveals what server
   * a person is on. Auspexen only.
   *  -- asuffield
   */

        
  /*
  ** the following two cases allow masks in NOTICEs
  ** (for OPERs only) (with +M -- asuffield)
  **
  ** Armin, 8Jun90 ([email protected])
  */
  if ((*nick == '$' || *nick == '>'))
    {

      if(!HasUmode(sptr,UMODE_MASSNOTICE))
        {
          sendto_one(sptr, form_str(ERR_NOSUCHNICK),
                     me.name, parv[0], nick);
          return -1;
        }

#ifdef NEED_TLD_FOR_MASS_NOTICE
      if (!(s = (char *)strrchr(nick, '.')))
        {
          sendto_one(sptr, form_str(ERR_NOTOPLEVEL),
                     me.name, parv[0], nick);
          msgs++;
	  continue;
        }
      while (*++s)
        if (*s == '.' || *s == '*' || *s == '?')
          break;
      if (*s == '*' || *s == '?')
        {
          sendto_one(sptr, form_str(ERR_WILDTOPLEVEL),
                     me.name, parv[0], nick);
	  msgs++;
	  continue;
        }
#endif /* NEED_TLD_FOR_MASS_NOTICE */
        
      sendto_match_butone(IsServer(cptr) ? cptr : NULL, 
                          sptr, nick + 1,
                          (*nick == '>') ? MATCH_HOST :
                          MATCH_SERVER,
                          ":%s %s %s :%s", parv[0],
                          cmd, nick, parv[2]);
      msgs++;
      continue;
    }
        
  /*
  ** user[%host]@server addressed?
  */
  if ((server = (char *)strchr(nick, '@')) &&
      (acptr = find_server(server + 1)))
    {
      int count = 0;

      /* Disable the whole farping mess for non-auspexen
       *  -- asuffield
       */
      if (!HasUmode(sptr,UMODE_AUSPEX))
        {
          sendto_one(sptr, form_str(ERR_NOSUCHNICK),
                     me.name, parv[0], nick);
 	  msgs++;
	  continue;
        }

      /* Disable the user%host@server form for non-opers
       * -Dianora
       */

      /* Disabled. This isn't very useful and I don't feel like mucking around with privs for it
       *  -- asuffield */
      if((char *)strchr(nick,'%'))
        {
          sendto_one(sptr, form_str(ERR_NOSUCHNICK),
                     me.name, parv[0], nick);
 	  msgs++;
	  continue;
        }
        
      /*
      ** Not destined for a user on me :-(
      */
      if (!IsMe(acptr))
        {
          sendto_one(acptr,":%s %s %s :%s", parv[0],
                     cmd, nick, parv[2]);
          msgs++;
          continue;
        }

      *server = '\0';

      /* special case opers@server */
      /* We don't want this on OPN -- asuffield */
#if 0
      if(!irccmp(nick,"opers") && SendWallops(sptr))
        {
          sendto_realops("To opers: From %s: %s",sptr->name,parv[2]);
          msgs++;
          continue;
        }
#endif
        
      if ((host = (char *)strchr(nick, '%')))
        *host++ = '\0';

      /*
      ** Look for users which match the destination host
      ** (no host == wildcard) and if one and one only is
      ** found connected to me, deliver message!
      */
      acptr = find_userhost(nick, host, NULL, &count);
      if (server)
        *server = '@';
      if (host)
        *--host = '%';
      if (acptr)
        {
          if (count == 1)
            sendto_prefix_one(acptr, sptr,
                              ":%s %s %s :%s",
                              parv[0], cmd,
                              nick, parv[2]);
          else if (!notice)
            sendto_one(sptr,
                       form_str(ERR_TOOMANYTARGETS),
                       me.name, parv[0], nick, MAX_MULTI_MESSAGES);
        }
      if (acptr)
	{
	  msgs++;
	  continue;
	}
    }
  /* Let's not send these remotely for channels */
  if (MyConnect(sptr) || (nick[0] != '#'))
    sendto_one(sptr, form_str(ERR_NOSUCHNICK), me.name,
	       parv[0], nick);
  msgs++;
  }
  if (strtok(NULL, ","))
    sendto_one(sptr, form_str(ERR_TOOMANYTARGETS),
                     me.name, parv[0], cmd, MAX_MULTI_MESSAGES);
  return 0;
}
コード例 #6
0
ファイル: m_kill.c プロジェクト: cyocom/Technokats-Website
/*
** m_kill
**	parv[0] = sender prefix
**	parv[1] = kill victim(s) - comma separated list
**	parv[2] = kill path
*/
DLLFUNC int  m_kill(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient *acptr;
	anUser *auser;
	char inpath[HOSTLEN * 2 + USERLEN + 5];
	char *oinpath = get_client_name(cptr, FALSE);
	char *user, *path, *killer, *nick, *p, *s;
	int  chasing = 0, kcount = 0;



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

	user = parv[1];
	path = parv[2];		/* Either defined or NULL (parc >= 2!!) */

	strlcpy(inpath, oinpath, sizeof inpath);

#ifndef ROXnet
	if (IsServer(cptr) && (s = (char *)index(inpath, '.')) != NULL)
		*s = '\0';	/* Truncate at first "." */
#endif

	if (!IsPrivileged(cptr))
	{
		sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
		return 0;
	}
	if (IsAnOper(cptr))
	{
		if (BadPtr(path))
		{
			sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
			    me.name, parv[0], "KILL");
			return 0;
		}
		if (strlen(path) > (size_t)TOPICLEN)
			path[TOPICLEN] = '\0';
	}

	if (MyClient(sptr))
		user = (char *)canonize(user);

	for (p = NULL, nick = strtoken(&p, user, ","); nick;
	    nick = strtoken(&p, NULL, ","))
	{

		chasing = 0;

		if (!(acptr = find_client(nick, NULL)))
		{
			/*
			   ** If the user has recently changed nick, we automaticly
			   ** rewrite the KILL for this new nickname--this keeps
			   ** servers in synch when nick change and kill collide
			 */
			if (!(acptr =
			    get_history(nick, (long)KILLCHASETIMELIMIT)))
			{
				sendto_one(sptr, err_str(ERR_NOSUCHNICK),
				    me.name, parv[0], nick);
				continue;
			}
			sendto_one(sptr,
			    ":%s %s %s :*** KILL changed from %s to %s",
			    me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], nick, acptr->name);
			chasing = 1;
		}
		if ((!MyConnect(acptr) && MyClient(cptr) && !OPCanGKill(cptr))
		    || (MyConnect(acptr) && MyClient(cptr)
		    && !OPCanLKill(cptr)))
		{
			sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
			    parv[0]);
			continue;
		}
		if (IsServer(acptr) || IsMe(acptr))
		{
			sendto_one(sptr, err_str(ERR_CANTKILLSERVER),
			    me.name, parv[0]);
			continue;
		}
		if (!IsPerson(acptr))
		{
			/* Nick exists but user is not registered yet: IOTW "doesn't exist". -- Syzop */
			sendto_one(sptr, err_str(ERR_NOSUCHNICK),
			    me.name, parv[0], nick);
			continue;
		}

		if (IsServices(acptr) && !(IsNetAdmin(sptr) || IsULine(sptr)))
		{
			sendto_one(sptr, err_str(ERR_KILLDENY), me.name,
			    parv[0], parv[1]);
			return 0;
		}
		/* From here on, the kill is probably going to be successful. */

		kcount++;

		if (!IsServer(sptr) && (kcount > MAXKILLS))
		{
			sendto_one(sptr,
			    ":%s %s %s :*** Too many targets, kill list was truncated. Maximum is %d.",
			    me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], MAXKILLS);
			break;
		}
		if (!IsServer(cptr))
		{
			/*
			   ** The kill originates from this server, initialize path.
			   ** (In which case the 'path' may contain user suplied
			   ** explanation ...or some nasty comment, sigh... >;-)
			   **
			   **   ...!operhost!oper
			   **   ...!operhost!oper (comment)
			 */
			strlcpy(inpath, GetHost(cptr), sizeof inpath);
			if (kcount < 2) {	/* Only check the path the first time
					   around, or it gets appended to itself. */
				if (!BadPtr(path))
				{
					(void)ircsprintf(buf, "%s%s (%s)",
					    cptr->name,
					    IsOper(sptr) ? "" : "(L)", path);
					path = buf;
				}
				else
					path = cptr->name;
			}
		}
		else if (BadPtr(path))
			path = "*no-path*";	/* Bogus server sending??? */
		/*
		   ** Notify all *local* opers about the KILL (this includes the one
		   ** originating the kill, if from this server--the special numeric
		   ** reply message is not generated anymore).
		   **
		   ** Note: "acptr->name" is used instead of "user" because we may
		   **    have changed the target because of the nickname change.
		 */

		auser = acptr->user;

		sendto_snomask_normal(SNO_KILLS,
		    "*** Notice -- Received KILL message for %s!%s@%s from %s Path: %s!%s",
		    acptr->name, auser->username,
		    IsHidden(acptr) ? auser->virthost : auser->realhost,
		    parv[0], inpath, path);
#if defined(USE_SYSLOG) && defined(SYSLOG_KILL)
		if (IsOper(sptr))
			syslog(LOG_DEBUG, "KILL From %s For %s Path %s!%s",
			    parv[0], acptr->name, inpath, path);
#endif
		/*
		 * By otherguy
		*/
                ircd_log
                    (LOG_KILL, "KILL (%s) by  %s(%s!%s)",
                           make_nick_user_host
                     (acptr->name, acptr->user->username, GetHost(acptr)),
                            parv[0],
                            inpath,
                            path);
		/*
		   ** And pass on the message to other servers. Note, that if KILL
		   ** was changed, the message has to be sent to all links, also
		   ** back.
		   ** Suicide kills are NOT passed on --SRB
		 */
		if (!MyConnect(acptr) || !MyConnect(sptr) || !IsAnOper(sptr))
		{
			sendto_serv_butone(cptr, ":%s KILL %s :%s!%s",
			    parv[0], acptr->name, inpath, path);
			if (chasing && IsServer(cptr))
				sendto_one(cptr, ":%s KILL %s :%s!%s",
				    me.name, acptr->name, inpath, path);
			acptr->flags |= FLAGS_KILLED;
		}

		/*
		   ** Tell the victim she/he has been zapped, but *only* if
		   ** the victim is on current server--no sense in sending the
		   ** notification chasing the above kill, it won't get far
		   ** anyway (as this user don't exist there any more either)
		 */
		if (MyConnect(acptr))
			sendto_prefix_one(acptr, sptr, ":%s KILL %s :%s!%s",
			    parv[0], acptr->name, inpath, path);
		/*
		   ** Set FLAGS_KILLED. This prevents exit_one_client from sending
		   ** the unnecessary QUIT for this. (This flag should never be
		   ** set in any other place)
		 */
		if (MyConnect(acptr) && MyConnect(sptr) && IsAnOper(sptr))

			(void)ircsprintf(buf2, "[%s] Local kill by %s (%s)",
			    me.name, sptr->name,
			    BadPtr(parv[2]) ? sptr->name : parv[2]);
		else
		{
			if ((killer = index(path, ' ')))
			{
				while ((killer >= path) && *killer && *killer != '!')
					killer--;
				if (!*killer)
					killer = path;
				else
					killer++;
			}
			else
				killer = path;
			(void)ircsprintf(buf2, "Killed (%s)", killer);
		}

		if (MyClient(sptr))
			RunHook3(HOOKTYPE_LOCAL_KILL, sptr, acptr, parv[2]);
		if (exit_client(cptr, acptr, sptr, buf2) == FLUSH_BUFFER)
			return FLUSH_BUFFER;
	}
	return 0;
}
コード例 #7
0
ファイル: s_numeric.c プロジェクト: Adam-/unrealircd
/*
** DoNumeric (replacement for the old do_numeric)
**
**	parc	number of arguments ('sender' counted as one!)
**	parv[0]	pointer to 'sender' (may point to empty string) (not used)
**	parv[1]..parv[parc-1]
**		pointers to additional parameters, this is a NULL
**		terminated list (parv[parc] == NULL).
**
** *WARNING*
**	Numerics are mostly error reports. If there is something
**	wrong with the message, just *DROP* it! Don't even think of
**	sending back a neat error message -- big danger of creating
**	a ping pong error message...
*/
int  do_numeric(int numeric, aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient *acptr;
	aChannel *chptr;
	char *nick, *p;
	int  i;

	/* Is this an outgoing connect, and we get a numeric 451 (not registered) back for the
	 * magic command __PANGPANG__ and we did not send a SERVER message yet?
	 * Then this means we are dealing with an Unreal server <3.2.9 and we should send the
	 * SERVER command right now.
	 */
	if (!IsServer(sptr) && !IsPerson(sptr) && (numeric == 451) && (parc > 2) && strstr(parv[1], "__PANGPANG__") &&
	    IsHandshake(cptr) && sptr->serv && !IsServerSent(sptr))
	{
		send_server_message(sptr);
		return 0;
	}

	if (parc < 1 || !IsServer(sptr))
		return 0;
	/* Remap low number numerics. */
	if (numeric < 100)
		numeric += 100;

	/*
	   ** Prepare the parameter portion of the message into 'buffer'.
	   ** (Because the buffer is twice as large as the message buffer
	   ** for the socket, no overflow can occur here... ...on current
	   ** assumptions--bets are off, if these are changed --msa)
	   ** Note: if buffer is non-empty, it will begin with SPACE.
	 */
	buffer[0] = '\0';
	if (parc > 2)
	{
		/*
		 * For strlcat nazis, please read above
		*/
		for (i = 2; i < (parc - 1); i++)
		{
			(void)strcat(buffer, " ");
			(void)strcat(buffer, parv[i]);
		}
		(void)strcat(buffer, " :");
		(void)strcat(buffer, parv[parc - 1]);
	}
	else
		sendto_realops("do_numeric( %i, %s, %s, %i, { %s, %s } )!",
		    numeric, cptr->name, sptr->name, parc,
		    parv[0], parv[1] ? parv[1] : "<null>");
	for (; (nick = strtoken(&p, parv[1], ",")); parv[1] = NULL)
	{
		if ((acptr = find_client(nick, (aClient *)NULL)))
		{
			/*
			   ** Drop to bit bucket if for me...
			   ** ...one might consider sendto_ops
			   ** here... --msa
			   ** And so it was done. -avalon
			   ** And regretted. Dont do it that way. Make sure
			   ** it goes only to non-servers. -avalon
			   ** Check added to make sure servers don't try to loop
			   ** with numerics which can happen with nick collisions.
			   ** - Avalon
			 */
			if (!IsMe(acptr) && IsPerson(acptr))
			{
				/* Added for .U3.2. drop remote 'You are not on
				   ** that channel', we should be synced anyway,
				   ** and this is an annoying message with TSpre7
				   ** still on the net; would result in numeric 442 for
				   ** every KICK... Can be removed when TSpre7 is gone.
				   ** --Run
				   if (numeric==ERR_NOTONCHANNEL) return 0;
				 */

				sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
				    parv[0], numeric, nick, buffer);
			}
			else if (IsServer(acptr) && acptr->from != cptr)
				sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
				    parv[0], numeric, nick, buffer);
		}
		else if ((acptr = find_server_quick(nick)))
		{
			if (!IsMe(acptr) && acptr->from != cptr)
				sendto_prefix_one(acptr, sptr, ":%s %d %s%s",
				    parv[0], numeric, nick, buffer);
		}
		else if ((chptr = find_channel(nick, (aChannel *)NULL)))
			sendto_channel_butone(cptr, sptr, chptr, ":%s %d %s%s",
			    parv[0], numeric, chptr->chname, buffer);
	}
	return 0;
}
コード例 #8
0
ファイル: s_numeric.c プロジェクト: mysidia/snservices1
/*
** DoNumeric (replacement for the old do_numeric)
**
**	parc	number of arguments ('sender' counted as one!)
**	parv[0]	pointer to 'sender' (may point to empty string) (not used)
**	parv[1]..parv[parc-1]
**		pointers to additional parameters, this is a NULL
**		terminated list (parv[parc] == NULL).
**
** *WARNING*
**	Numerics are mostly error reports. If there is something
**	wrong with the message, just *DROP* it! Don't even think of
**	sending back a neat error message -- big danger of creating
**	a ping pong error message...
*/
int	do_numeric(int numeric, aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient *acptr;
	aChannel *chptr;
	char	*nick, *p;
	int	i;

	if (parc < 1 || !IsServer(sptr))
		return 0;
	/* Remap low number numerics. */
	if (numeric < 100)
		numeric += 100;
	/*
	** Prepare the parameter portion of the message into 'buffer'.
	** (Because the buffer is twice as large as the message buffer
	** for the socket, no overflow can occur here... ...on current
	** assumptions--bets are off, if these are changed --msa)
	** Note: if buffer is non-empty, it will begin with SPACE.
	*/
	buffer[0] = '\0';
	if (parc > 1)
	    {
		for (i = 2; i < (parc - 1); i++)
		    {
			strcat(buffer, " ");
			strcat(buffer, parv[i]);
		    }
		strcat(buffer, " :");
		strcat(buffer, parv[parc-1]);
	    }
	for (; (nick = strtok_r(parv[1], ",", &p)); parv[1] = NULL)
	    {
		if ((acptr = find_client(nick, (aClient *)NULL)))
		    {
			/*
			** Drop to bit bucket if for me...
			** ...one might consider sendto_ops
			** here... --msa
			** And so it was done. -avalon
			** And regretted. Dont do it that way. Make sure
			** it goes only to non-servers. -avalon
			** Check added to make sure servers don't try to loop
			** with numerics which can happen with nick collisions.
			** - Avalon
			*/
			if (!IsMe(acptr) && IsPerson(acptr))
			{
			/* Added for .U3.2. drop remote 'You are not on
			** that channel', we should be synced anyway,
			** and this is an annoying message with TSpre7
			** still on the net; would result in numeric 442 for
			** every KICK... Can be removed when TSpre7 is gone.
			** --Run
			*/
				if (numeric==ERR_NOTONCHANNEL) return 0;

				sendto_prefix_one(acptr, sptr,":%s %d %s%s",
					parv[0], numeric, nick, buffer);
			}
			else if (IsServer(acptr) && acptr->from != cptr)
				sendto_prefix_one(acptr, sptr,":%s %d %s%s",
					parv[0], numeric, nick, buffer);
		    }
		else if ((acptr = find_server(nick, (aClient *)NULL)))
		    {
			if (!IsMe(acptr) && acptr->from != cptr)
				sendto_prefix_one(acptr, sptr,":%s %d %s%s",
					parv[0], numeric, nick, buffer);
		    }
		else if ((chptr = find_channel(nick, (aChannel *)NULL)))
			sendto_channel_butone(cptr,sptr,chptr,":%s %d %s%s",
					      parv[0],
					      numeric, chptr->chname, buffer);
	    }
	return 0;
}