Esempio n. 1
0
/**
 * Part client from channel.
 * This function lets a client part from a channel. First, the function checks
 * if the channel exists and the client is a member of it and sends out
 * appropriate error messages if not. The real work is done by the function
 * Remove_Client().
 */
GLOBAL bool
Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Reason)
{
	CHANNEL *chan;

	assert(Client != NULL);
	assert(Name != NULL);
	assert(Reason != NULL);

	/* Check that specified channel exists */
	chan = Channel_Search(Name);
	if (!chan) {
		IRC_WriteErrClient(Client, ERR_NOSUCHCHANNEL_MSG,
				   Client_ID(Client), Name);
		return false;
	}

	/* Check that the client is in the channel */
	if (!Get_Cl2Chan(chan, Client)) {
		IRC_WriteErrClient(Client, ERR_NOTONCHANNEL_MSG,
				   Client_ID(Client), Name);
		return false;
	}

	if (Conf_MorePrivacy)
		Reason = "";

	/* Part client from channel */
	if (!Remove_Client(REMOVE_PART, chan, Client, Origin, Reason, true))
		return false;
	else
		return true;
} /* Channel_Part */
Esempio n. 2
0
GLOBAL void
Channel_Quit( CLIENT *Client, const char *Reason )
{
	CHANNEL *c, *next_c;

	assert( Client != NULL );
	assert( Reason != NULL );

	if (Conf_MorePrivacy)
		Reason = "";

	IRC_WriteStrRelatedPrefix( Client, Client, false, "QUIT :%s", Reason );

	c = My_Channels;
	while( c )
	{
		next_c = c->next;
		Remove_Client( REMOVE_QUIT, c, Client, Client, Reason, false );
		c = next_c;
	}
} /* Channel_Quit */
Esempio n. 3
0
/**
 * Kick user from Channel
 */
GLOBAL void
Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
	     const char *Reason )
{
	CHANNEL *chan;
	bool can_kick = false;

	assert(Peer != NULL);
	assert(Target != NULL);
	assert(Origin != NULL);
	assert(Name != NULL);
	assert(Reason != NULL);

	/* Check that channel exists */
	chan = Channel_Search( Name );
	if (!chan) {
		IRC_WriteErrClient(Origin, ERR_NOSUCHCHANNEL_MSG,
				   Client_ID(Origin), Name);
		return;
	}

	if (Client_Type(Peer) != CLIENT_SERVER &&
	    Client_Type(Origin) != CLIENT_SERVICE) {
		/* Check that user is on the specified channel */
		if (!Channel_IsMemberOf(chan, Origin)) {
			IRC_WriteErrClient(Origin, ERR_NOTONCHANNEL_MSG,
					   Client_ID(Origin), Name);
			return;
		}
	}

	/* Check that the client to be kicked is on the specified channel */
	if (!Channel_IsMemberOf(chan, Target)) {
		IRC_WriteErrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
				   Client_ID(Origin), Client_ID(Target), Name );
		return;
	}

	if(Client_Type(Peer) == CLIENT_USER) {
		/* Channel mode 'Q' and user mode 'q' on target: nobody but
		 * IRC Operators and servers can kick the target user */
		if ((Channel_HasMode(chan, 'Q')
		     || Client_HasMode(Target, 'q')
		     || Client_Type(Target) == CLIENT_SERVICE)
		    && !Client_HasMode(Origin, 'o')) {
			IRC_WriteErrClient(Origin, ERR_KICKDENY_MSG,
					   Client_ID(Origin), Name,
					   Client_ID(Target));
			return;
		}

		/* Check if client has the rights to kick target */

		/* Owner can kick everyone */
		if (Channel_UserHasMode(chan, Peer, 'q'))
			can_kick = true;

		/* Admin can't kick owner */
		else if (Channel_UserHasMode(chan, Peer, 'a') &&
		    !Channel_UserHasMode(chan, Target, 'q'))
			can_kick = true;

		/* Op can't kick owner | admin */
		else if (Channel_UserHasMode(chan, Peer, 'o') &&
		    !Channel_UserHasMode(chan, Target, 'q') &&
		    !Channel_UserHasMode(chan, Target, 'a'))
			can_kick = true;
			
		/* Half Op can't kick owner | admin | op */ 
		else if (Channel_UserHasMode(chan, Peer, 'h') &&
		    !Channel_UserHasMode(chan, Target, 'q') &&
		    !Channel_UserHasMode(chan, Target, 'a') &&
		    !Channel_UserHasMode(chan, Target, 'o'))
			can_kick = true;
		
		/* IRC operators & IRCd with OperCanMode enabled
		 * can kick anyways regardless of privilege */	
		else if(Client_HasMode(Origin, 'o') && Conf_OperCanMode)
		    can_kick = true;

		if(!can_kick) {
			IRC_WriteErrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
					   Client_ID(Origin), Name);
			return;
		}
	}

	/* Kick Client from channel */
	Remove_Client( REMOVE_KICK, chan, Target, Origin, Reason, true);
} /* Channel_Kick */
Esempio n. 4
0
/**
 * Kick user from Channel
 */
GLOBAL void
Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
	     const char *Reason )
{
	CHANNEL *chan;
	char *ptr, *target_modes;
	bool can_kick = false;

	assert(Peer != NULL);
	assert(Target != NULL);
	assert(Origin != NULL);
	assert(Name != NULL);
	assert(Reason != NULL);

	/* Check that channel exists */
	chan = Channel_Search( Name );
	if( ! chan )
	{
		IRC_WriteStrClient( Origin, ERR_NOSUCHCHANNEL_MSG, Client_ID( Origin ), Name );
		return;
	}

	if (Client_Type(Peer) != CLIENT_SERVER &&
	    Client_Type(Origin) != CLIENT_SERVICE) {
		/* Check that user is on the specified channel */
		if (!Channel_IsMemberOf(chan, Origin)) {
			IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
					    Client_ID(Origin), Name);
			return;
		}
	}

	if(Client_Type(Peer) == CLIENT_USER) {
		/* Channel mode 'Q' and user mode 'q' on target: nobody but
		 * IRC Operators and servers can kick the target user */
		if ((strchr(Channel_Modes(chan), 'Q')
		     || Client_HasMode(Target, 'q')
		     || Client_Type(Target) == CLIENT_SERVICE)
		    && !Client_HasMode(Origin, 'o')) {
			IRC_WriteStrClient(Origin, ERR_KICKDENY_MSG,
					   Client_ID(Origin), Name,
					   Client_ID(Target));
			return;
		}

		/* Check if client has the rights to kick target */
		ptr = Channel_UserModes(chan, Peer);
		target_modes = Channel_UserModes(chan, Target);
		while(*ptr) {
			/* Owner can kick everyone */
			if ( *ptr == 'q') {
				can_kick = true;
				break;
			}
			/* Admin can't kick owner */
			if ( *ptr == 'a' ) {
				if (!strchr(target_modes, 'q')) {
					can_kick = true;
					break;
				}
			}
			/* Op can't kick owner | admin */
			if ( *ptr == 'o' ) {
				if (!strchr(target_modes, 'q') &&
				    !strchr(target_modes, 'a')) {
					can_kick = true;
					break;
				}
			}
			/* Half Op can't kick owner | admin | op */ 
			if ( *ptr == 'h' ) {
				if (!strchr(target_modes, 'q') &&
				    !strchr(target_modes, 'a') &&
				    !strchr(target_modes, 'o')) {
					can_kick = true;
					break;
				}
			}
			ptr++;
		}

		if(!can_kick) {
			IRC_WriteStrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
				Client_ID(Origin), Name);
			return;
		}
	}

	/* Check that the client to be kicked is on the specified channel */
	if (!Channel_IsMemberOf(chan, Target)) {
		IRC_WriteStrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
				   Client_ID(Origin), Client_ID(Target), Name );
		return;
	}

	/* Kick Client from channel */
	Remove_Client( REMOVE_KICK, chan, Target, Origin, Reason, true);
} /* Channel_Kick */