about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/conf.c26
-rw-r--r--src/ngircd/conf.h7
-rw-r--r--src/ngircd/irc-mode.c16
3 files changed, 37 insertions, 12 deletions
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
index 312ebff9..f00c2633 100644
--- a/src/ngircd/conf.c
+++ b/src/ngircd/conf.c
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: conf.c,v 1.69 2005/03/02 16:07:31 alex Exp $";
+static char UNUSED id[] = "$Id: conf.c,v 1.70 2005/03/15 16:56:18 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -142,6 +142,7 @@ Conf_Test( VOID )
 	printf( "  PongTimeout = %d\n", Conf_PongTimeout );
 	printf( "  ConnectRetry = %d\n", Conf_ConnectRetry );
 	printf( "  OperCanUseMode = %s\n", Conf_OperCanMode == TRUE ? "yes" : "no" );
+	printf( "  OperServerMode = %s\n", Conf_OperServerMode == TRUE ? "yes" : "no" );
 	if( Conf_MaxConnections > 0 ) printf( "  MaxConnections = %ld\n", Conf_MaxConnections );
 	else printf( "  MaxConnections = -1\n" );
 	if( Conf_MaxConnectionsIP > 0 ) printf( "  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP );
@@ -374,6 +375,7 @@ Set_Defaults( BOOLEAN InitServers )
 	Conf_Channel_Count = 0;
 
 	Conf_OperCanMode = FALSE;
+	Conf_OperServerMode = FALSE;
 	
 	Conf_MaxConnections = -1;
 	Conf_MaxConnectionsIP = 5;
@@ -561,6 +563,17 @@ Read_Config( VOID )
 } /* Read_Config */
 
 
+LOCAL BOOLEAN
+Check_ArgIsTrue( const char *Arg )
+{
+	if( strcasecmp( Arg, "yes" ) == 0 ) return TRUE;
+	if( strcasecmp( Arg, "true" ) == 0 ) return TRUE;
+	if( atoi( Arg ) != 0 ) return TRUE;
+
+	return FALSE;
+} /* Check_ArgIsTrue */
+
+
 LOCAL VOID
 Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
 {
@@ -734,10 +747,13 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
 	if( strcasecmp( Var, "OperCanUseMode" ) == 0 )
 	{
 		/* Are IRC operators allowed to use MODE in channels they aren't Op in? */
-		if( strcasecmp( Arg, "yes" ) == 0 ) Conf_OperCanMode = TRUE;
-		else if( strcasecmp( Arg, "true" ) == 0 ) Conf_OperCanMode = TRUE;
-		else if( atoi( Arg ) != 0 ) Conf_OperCanMode = TRUE;
-		else Conf_OperCanMode = FALSE;
+		Conf_OperCanMode = Check_ArgIsTrue( Arg );
+		return;
+	}
+	if( strcasecmp( Var, "OperServerMode" ) == 0 )
+	{
+		/* Mask IRC operator as if coming from the server? (ircd-irc2 compat hack) */
+		Conf_OperServerMode = Check_ArgIsTrue( Arg );
 		return;
 	}
 	if( strcasecmp( Var, "MaxConnections" ) == 0 )
diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h
index 3c180160..797c5a5c 100644
--- a/src/ngircd/conf.h
+++ b/src/ngircd/conf.h
@@ -8,7 +8,7 @@
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
  *
- * $Id: conf.h,v 1.31 2005/03/02 16:07:31 alex Exp $
+ * $Id: conf.h,v 1.32 2005/03/15 16:56:18 alex Exp $
  *
  * Configuration management (header)
  */
@@ -114,6 +114,11 @@ GLOBAL INT Conf_Channel_Count;
 /* Are IRC operators allowed to always use MODE? */
 GLOBAL BOOLEAN Conf_OperCanMode;
 
+/* If an IRC op gives chanop privileges without being a chanop,
+ * ircd2 will ignore the command. This enables a workaround:
+ * It masks the command as coming from the server */
+GLOBAL BOOLEAN Conf_OperServerMode;
+
 /* Maximum number of connections to this server */
 GLOBAL LONG Conf_MaxConnections;
 
diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c
index 2f657f27..6fcb9e33 100644
--- a/src/ngircd/irc-mode.c
+++ b/src/ngircd/irc-mode.c
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: irc-mode.c,v 1.38 2005/03/05 11:44:01 alex Exp $";
+static char UNUSED id[] = "$Id: irc-mode.c,v 1.39 2005/03/15 16:56:18 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -242,7 +242,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 	/* Handle channel and channel-user modes */
 
 	CHAR the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr;
-	BOOLEAN ok, set, modeok, skiponce;
+	BOOLEAN ok, set, modeok = FALSE, skiponce, use_servermode = FALSE;
 	INT mode_arg, arg_arg;
 	CLIENT *client;
 	LONG l;
@@ -286,11 +286,13 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 
 		/* Is he channel operator? */
 		if( strchr( Channel_UserModes( Channel, Origin ), 'o' )) modeok = TRUE;
-		else modeok = FALSE;
-		if( Conf_OperCanMode )
+		else if( Conf_OperCanMode )
 		{
-			/* auch IRC-Operatoren duerfen MODE verwenden */
-			if( Client_OperByMe( Origin )) modeok = TRUE;
+			/* IRC-Operators can use MODE as well */
+			if( Client_OperByMe( Origin )) {
+				modeok = TRUE;
+				if ( Conf_OperServerMode ) use_servermode = TRUE; /* Change Origin to Server */
+			}
 		}
 	}
 	else modeok = TRUE;
@@ -584,6 +586,8 @@ chan_exit:
 		}
 		else
 		{
+			if ( use_servermode ) Origin = Client_ThisServer();
+
 			/* Send reply to client and inform other servers and channel users */
 			ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
 			IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );