]> arthur.barton.de Git - ngircd.git/blobdiff - src/ngircd/irc-server.c
IRC_SQUIT(): Fix use-after-free when unregistering the sending client
[ngircd.git] / src / ngircd / irc-server.c
index 6ca3c33288ebfd595084cf77a28863974957abbc..3f9753b9670d93205d5d6504e34e9f87e5984cdf 100644 (file)
@@ -31,6 +31,7 @@
 #include "parse.h"
 #include "numeric.h"
 #include "ngircd.h"
+#include "irc.h"
 #include "irc-info.h"
 #include "irc-write.h"
 #include "op.h"
@@ -185,6 +186,15 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
                if (!Client_CheckID(Client, Req->argv[0]))
                        return DISCONNECTED;
 
+               if (!Req->prefix) {
+                       /* We definitely need a prefix here! */
+                       Log(LOG_ALERT, "Got SERVER command without prefix! (on connection %d)",
+                           Client_Conn(Client));
+                       Conn_Close(Client_Conn(Client), NULL,
+                                  "SERVER command without prefix", true);
+                       return DISCONNECTED;
+               }
+
                from = Client_Search( Req->prefix );
                if (! from) {
                        /* Uh, Server, that introduced the new server is unknown?! */
@@ -282,7 +292,16 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
                        goto skip_njoin;
                }
 
-               Channel_Join(c, channame);
+               if (!Channel_Join(c, channame)) {
+                       /* Failed to join channel. Ooops!? */
+                       Log(LOG_ALERT,
+                           "Failed to join client \"%s\" to channel \"%s\" (NJOIN): killing it!",
+                           ptr, channame);
+                       IRC_KillClient(NULL, NULL, ptr, "Internal NJOIN error!");
+                       Log(LOG_DEBUG, "... done.");
+                       goto skip_njoin;
+               }
+
                chan = Channel_Search(channame);
                assert(chan != NULL);
 
@@ -348,7 +367,7 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req)
 {
        char msg[COMMAND_LEN], logmsg[COMMAND_LEN];
        CLIENT *from, *target;
-       CONN_ID con;
+       CONN_ID con, client_con;
        int loglevel;
 
        assert(Client != NULL);
@@ -388,6 +407,7 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req)
                return CONNECTED;
        }
 
+       client_con = Client_Conn(Client);
        con = Client_Conn(target);
 
        if (Req->argv[1][0])
@@ -409,7 +429,7 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req)
                                Req->argv[0], Client_ID(from),
                                Req->argv[1][0] ? Req->argv[1] : "-");
                Conn_Close(con, NULL, msg, true);
-               if (con == Client_Conn(Client))
+               if (con == client_con)
                        return DISCONNECTED;
        } else {
                /* This server is not directly connected, so the SQUIT must