]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-oper.c
CONNECT, DISCONNECT: generate WALLOPS messages
[ngircd-alex.git] / src / ngircd / irc-oper.c
index 736163c107e6b6b135ddde4370b8eb720811f77d..082414984df728ada9fdfae2aae7d6d5bb33c5ef 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
 
 #include "imp.h"
 #include <assert.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -50,6 +51,35 @@ Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
 } /* Bad_OperPass */
 
 
+/**
+ * Check that the client is an IRC operator allowed to administer this server.
+ */
+static bool
+Check_Oper(CLIENT * Client)
+{
+       if (!Client_HasMode(Client, 'o'))
+               return false;
+       if (!Client_OperByMe(Client) && !Conf_AllowRemoteOper)
+               return false;
+       /* The client is an local IRC operator, or this server is configured
+        * to trust remote operators. */
+       return true;
+} /* CheckOper */
+
+
+/**
+ * Return and log a "no privileges" message.
+ */
+static bool
+No_Privileges(CLIENT * Client, REQUEST * Req)
+{
+       Log(LOG_NOTICE, "No privileges: client \"%s\", command \"%s\"",
+           Client_Mask(Client), Req->command);
+       return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
+                                 Client_ID(Client));
+} /* PermissionDenied */
+
+
 GLOBAL bool
 IRC_OPER( CLIENT *Client, REQUEST *Req )
 {
@@ -98,10 +128,8 @@ IRC_DIE(CLIENT * Client, REQUEST * Req)
        assert(Client != NULL);
        assert(Req != NULL);
 
-       /* Not a local IRC operator? */
-       if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client)))
-               return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
-                                         Client_ID(Client));
+       if (!Check_Oper(Client))
+               return No_Privileges(Client, Req);
 
        /* Bad number of parameters? */
 #ifdef STRICT_RFC
@@ -140,8 +168,8 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
        assert( Client != NULL );
        assert( Req != NULL );
 
-       /* Not a local IRC operator? */
-       if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
+       if (!Check_Oper(Client))
+               return No_Privileges(Client, Req);
 
        /* Bad number of parameters? */
        if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -161,8 +189,8 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
        assert( Client != NULL );
        assert( Req != NULL );
 
-       /* Not a local IRC operator? */
-       if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
+       if (!Check_Oper(Client))
+               return No_Privileges(Client, Req);
 
        /* Bad number of parameters? */
        if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -179,14 +207,13 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
 GLOBAL bool
 IRC_CONNECT(CLIENT * Client, REQUEST * Req)
 {
+       char msg[LINE_LEN + 64];
 
        assert(Client != NULL);
        assert(Req != NULL);
 
-       /* Not a local IRC operator? */
-       if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client)))
-               return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
-                                         Client_ID(Client));
+       if (!Check_Oper(Client))
+               return No_Privileges(Client, Req);
 
        /* Bad number of parameters? */
        if ((Req->argc != 1) && (Req->argc != 2) && (Req->argc != 5))
@@ -198,6 +225,10 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
                return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
                                          Client_ID(Client), Req->command);
 
+       snprintf(msg, sizeof(msg), "Received CONNECT %s from %s",
+                Req->argv[0], Client_ID(Client));
+       IRC_SendWallops(Client_ThisServer(), Client_ThisServer(), msg);
+
        Log(LOG_NOTICE | LOG_snotice,
            "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(Client),
            Req->argv[0]);
@@ -231,41 +262,54 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
 } /* IRC_CONNECT */
 
 
+/**
+ * Disconnect (and disable) configured server.
+ */
 GLOBAL bool
-IRC_DISCONNECT(CLIENT *Client, REQUEST *Req )
+IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
 {
-       /* Disconnect and disable configured server */
-
        CONN_ID my_conn;
+       char msg[LINE_LEN + 64];
 
-       assert( Client != NULL );
-       assert( Req != NULL );
+       assert(Client != NULL);
+       assert(Req != NULL);
 
-       /* Not a local IRC operator? */
-       if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
+       if (!Check_Oper(Client))
+               return No_Privileges(Client, Req);
 
        /* Bad number of parameters? */
-       if( Req->argc != 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
+       if (Req->argc != 1)
+               return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+                                         Client_ID(Client), Req->command);
 
-       Log( LOG_NOTICE|LOG_snotice, "Got DISCONNECT command from \"%s\" for0 \"%s\".", Client_Mask( Client ), Req->argv[0]);
+       snprintf(msg, sizeof(msg), "Received DISCONNECT %s from %s",
+                Req->argv[0], Client_ID(Client));
+       IRC_SendWallops(Client_ThisServer(), Client_ThisServer(), msg);
+
+       Log(LOG_NOTICE | LOG_snotice,
+           "Got DISCONNECT command from \"%s\" for \"%s\".",
+           Client_Mask(Client), Req->argv[0]);
 
        /* Save ID of this connection */
-       my_conn = Client_Conn( Client );
+       my_conn = Client_Conn(Client);
 
-       /* Connect configured server */
-       if( ! Conf_DisableServer( Req->argv[0] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
+       /* Disconnect configured server */
+       if (!Conf_DisableServer(Req->argv[0]))
+               return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
+                                         Client_ID(Client), Req->argv[0]);
 
        /* Are we still connected or were we killed, too? */
-       if( Conn_GetClient( my_conn )) return CONNECTED;
-       else return DISCONNECTED;
-} /* IRC_CONNECT */
+       if (Conn_GetClient(my_conn))
+               return CONNECTED;
+       else
+               return DISCONNECTED;
+} /* IRC_DISCONNECT */
 
 
 GLOBAL bool
 IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
 {
-       CLIENT *to, *from;
-       int client_type;
+       CLIENT *from;
 
        assert( Client != NULL );
        assert( Req != NULL );
@@ -273,8 +317,7 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
        if (Req->argc != 1)
                return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
 
-       client_type = Client_Type(Client);
-       switch (client_type) {
+       switch (Client_Type(Client)) {
        case CLIENT_USER:
                if (!Client_OperByMe(Client))
                        return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client));
@@ -290,25 +333,9 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
        if (!from)
                return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
 
-       for (to=Client_First(); to != NULL; to=Client_Next(to)) {
-               if (Client_Conn(to) < 0) /* no local connection or WALLOPS origin */
-                       continue;
-
-               client_type = Client_Type(to);
-               switch (client_type) {
-               case CLIENT_USER:
-                       if (Client_HasMode(to, 'w'))
-                               IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
-                       break;
-               case CLIENT_SERVER:
-                       if (to != Client)
-                               IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
-                       break;
-               }
-       }
+       IRC_SendWallops(Client, from, Req->argv[0]);
        return CONNECTED;
-}
-
+} /* IRC_WALLOPS */
 
 
 /* -eof- */