repo: ngircd
action: commit
revision: 
path_from: 
revision_from: 8d9cfa157a7fd067dab3483614d427f35dfa4ad1:
path_to: 
revision_to: 
git.thebackupbox.net
ngircd
git clone git://git.thebackupbox.net/ngircd
commit 8d9cfa157a7fd067dab3483614d427f35dfa4ad1
Author: Alexander Barton 
Date:   Fri Oct 19 19:45:44 2012 +0200

    Allow remote servers and IRC Ops to change channel topics

    Remote servers are always allowed to change all channel topics,
    and IRC Operators are allowed to change all channel topics if the
    configuration option "OperCanUseMode" is enabled.

    Bug introduced by commit 7b01bb8 and reported by DNS777.

diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c
index 4a157d67e5fca76d8461f421644da3d00e7b7dd0..
index ..f9d2dc125d3708b11ad629ed9551b7f08f4b2598 100644
--- a/src/ngircd/irc-channel.c
+++ b/src/ngircd/irc-channel.c
@@ -512,7 +512,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 	CHANNEL *chan;
 	CLIENT *from;
 	char *topic;
-	bool r, is_oper;
+	bool r, topic_power;

 	assert( Client != NULL );
 	assert( Req != NULL );
@@ -535,11 +535,17 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 		return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
 					  Client_ID(from), Req->argv[0]);

-	/* Only IRC opers and channel members allowed */
-	is_oper = Client_OperByMe(from);
-	if (!Channel_IsMemberOf(chan, from) && !is_oper)
-		return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
-					  Client_ID(from), Req->argv[0]);
+	/* Only remote servers and channel members are allowed to change the
+	 * channel topic, and IRC opreators when the Conf_OperCanMode option
+	 * is set in the server configuration. */
+	if (Client_Type(Client) != CLIENT_SERVER) {
+		topic_power = Client_HasMode(from, 'o');
+		if (!Channel_IsMemberOf(chan, from)
+		    && !(Conf_OperCanMode && topic_power))
+			return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
+						  Client_ID(from), Req->argv[0]);
+	} else
+		topic_power = true;

 	if (Req->argc == 1) {
 		/* Request actual topic */
@@ -567,11 +573,11 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )

 	if (strchr(Channel_Modes(chan), 't')) {
 		/* Topic Lock. Is the user a channel op or IRC operator? */
-		if(!strchr(Channel_UserModes(chan, from), 'h') &&
+		if(!topic_power &&
+		   !strchr(Channel_UserModes(chan, from), 'h') &&
 		   !strchr(Channel_UserModes(chan, from), 'o') &&
 		   !strchr(Channel_UserModes(chan, from), 'a') &&
-		   !strchr(Channel_UserModes(chan, from), 'q') &&
-		   !is_oper)
+		   !strchr(Channel_UserModes(chan, from), 'q'))
 			return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
 						  Client_ID(from),
 						  Channel_Name(chan));

-----END OF PAGE-----