about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/irc-channel.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c
index 8aa27c01..81a9eb2e 100644
--- a/src/ngircd/irc-channel.c
+++ b/src/ngircd/irc-channel.c
@@ -407,7 +407,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 	CHANNEL *chan;
 	CLIENT *from;
 	char *topic;
-	bool r;
+	bool onchannel, topicok, use_servermode, r;
 
 	assert( Client != NULL );
 	assert( Req != NULL );
@@ -430,7 +430,10 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 		return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
 					  Client_ID(from), Req->argv[0]);
 
-	if (!Channel_IsMemberOf(chan, from))
+	Channel_CheckAdminRights(chan, Client, from,
+				 &onchannel, &topicok, &use_servermode);
+
+	if (!onchannel && !topicok)
 		return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
 					  Client_ID(from), Req->argv[0]);
 
@@ -457,8 +460,8 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 	}
 
 	if (strchr(Channel_Modes(chan), 't')) {
-		/* Topic Lock. Is the user a channel operator? */
-		if (!strchr(Channel_UserModes(chan, from), 'o'))
+		/* Topic Lock. Is the user a channel or IRC operator? */
+		if (!topicok)
 			return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
 						  Client_ID(from),
 						  Channel_Name(chan));
@@ -470,6 +473,9 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 		 Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
 		 Req->argv[1][0] ? Req->argv[1] : "<none>");
 
+	if (use_servermode)
+		from = Client_ThisServer();
+
 	/* Update channel and forward new topic to other servers */
 	if (!Channel_IsLocal(chan))
 		IRC_WriteStrServersPrefix(Client, from, "TOPIC %s :%s",