prevent users from executing CrossChannel commands (without being in the target chann...
authorpk910 <philipp@zoelle1.de>
Sat, 10 Dec 2011 04:22:15 +0000 (05:22 +0100)
committerpk910 <philipp@zoelle1.de>
Sat, 10 Dec 2011 04:22:15 +0000 (05:22 +0100)
src/modcmd.c

index f6ff75fca8e6fffb7e6b31cbdb54c96eb1905b1f..420567f825e7beda92b548c3c83e0c2ff8b14181 100644 (file)
@@ -69,6 +69,7 @@ static const struct default_language_entry msgtab[] = {
     {"MODCMD_PUBCMD",           "Public commands in $b%s$b are restricted."}, /* {ARGS: "#TestChan"} */
     {"MODCMD_ACCESS_DENIED",    "Access denied."},
     {"MODCMD_SUBCOMMANDS",      "Subcommands of %s: %s"}, /* {ARGS: "bot", "ADD, DEL, EDIT"} */
+    {"MODCMD_CROSSCHAN",        "You must be in %s (or on its userlist) to use this command."},
     {NULL, NULL}
 };
 
@@ -319,7 +320,7 @@ static void handle_command(struct ClientSocket *client, struct UserNode *user, s
                 reply(tmp_text_client, user, "MODCMD_CHAN_REQUIRED");
                 break;
             }
-            if((cbind->func->flags & CMDFLAG_CHECK_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) {
+            if(((cbind->func->flags & CMDFLAG_CHECK_AUTH) || (chan && chan != sent_chan && !isUserOnChan(user, chan))) && !(user->flags & USERFLAG_ISAUTHED)) {
                 //check auth...
                 struct command_check_user_cache *data = malloc(sizeof(*data));
                 char **temp_argv = malloc(argc*sizeof(*temp_argv));
@@ -354,18 +355,41 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u
     MYSQL_RES *res;
     MYSQL_ROW row;
     int uaccess;
+    char requested_uaccess = 0;
     int eventflags = (cbind->func->flags & (CMDFLAG_LOG | CMDFLAG_OPLOG));
     if((cbind->func->flags & CMDFLAG_REQUIRE_AUTH) && !(user->flags & USERFLAG_ISAUTHED)) {
         reply(tmp_text_client, user, "MODCMD_AUTH_REQUIRED");
         return;
     }
+    if(chan && sent_chan != chan && !isUserOnChan(user, chan)) {
+        char user_in_chan = 0;
+        if((user->flags & USERFLAG_ISAUTHED)) {
+            //maybe there's another user authed to user->auth on the channel...
+            struct ChanUser *cchanuser;
+            for(cchanuser = getChannelUsers(chan, NULL); cchanuser; cchanuser = getChannelUsers(chan, cchanuser)) {
+                if((cchanuser->user->flags & USERFLAG_ISAUTHED) && !stricmp(user->auth, cchanuser->user->auth)) {
+                    user_in_chan = 1;
+                    break;
+                }
+            }
+        }
+        if(!user_in_chan) {
+            //check if we are allowed to execute commands in this channel
+            requested_uaccess = 1;
+            uaccess = getChannelAccess(user, chan);
+            if(!uaccess) {
+                reply(tmp_text_client, user, "MODCMD_CROSSCHAN", chan->name);
+                return;
+            }
+        }
+    }
     if(sent_chan && sent_chan != chan) {
         //check pubcmd of this channel
         printf_mysql_query("SELECT `channel_pubcmd` FROM `channels` WHERE `channel_name` = '%s'", escape_string(sent_chan->name));
         res = mysql_use();
         if ((row = mysql_fetch_row(res)) != NULL) {
-            uaccess = getChannelAccess(user, sent_chan);
-            if(row[0] && uaccess < atoi(row[0]) && !isGodMode(user)) { //NOTE: HARDCODED DEFAULT: pubcmd = 0
+            int saccess = getChannelAccess(user, sent_chan);
+            if(row[0] && saccess < atoi(row[0]) && !isGodMode(user)) { //NOTE: HARDCODED DEFAULT: pubcmd = 0
                 reply(tmp_text_client, user, "MODCMD_PUBCMD", sent_chan->name);
                 return;
             }
@@ -424,7 +448,7 @@ static void handle_command_async(struct ClientSocket *client, struct UserNode *u
                 chan->flags |= CHANFLAG_CHAN_REGISTERED;
                 chan->channel_id = atoi(row[0]);
                 if((sent_chan && sent_chan == chan) || access_count || minaccess) {
-                    uaccess = getChannelAccess(user, chan);
+                    if(!requested_uaccess) uaccess = getChannelAccess(user, chan);
                     if(uaccess < minaccess && isGodMode(user)) {
                         eventflags |= CMDFLAG_OPLOG;
                     } else if(uaccess < minaccess) {