Go through whole list of pending commands when deleting by
[silc.git] / apps / silcd / command.c
index 93e94e80bca35c2c41f56685ad9820e0ba9c95c6..1b5a3f27676cc78db9b2cb15bd97cef9e0356acc 100644 (file)
@@ -368,7 +368,7 @@ void silc_server_command_pending_del(SilcServer server,
   while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
     if (r->reply_cmd == reply_cmd && r->ident == ident) {
       silc_dlist_del(server->pending_commands, r);
-      break;
+      silc_free(r);
     }
   }
 }
@@ -1617,6 +1617,7 @@ silc_server_command_identify_parse(SilcServerCommandContext cmd,
        break;
       }
 
+      silc_id_payload_free(idp);
       silc_free(id);
     }
   }
@@ -3692,7 +3693,7 @@ SILC_SERVER_CMD_FUNC(join)
        /* Save channel passphrase, if user provided it successfully */
        unsigned char *pa;
        SilcUInt32 pa_len;
-       pa = silc_argument_get_arg_type(reply->args, 3, &pa_len);
+       pa = silc_argument_get_arg_type(cmd->args, 3, &pa_len);
        if (pa) {
          silc_free(channel->passphrase);
          channel->passphrase = silc_memdup(pa, pa_len);
@@ -3958,7 +3959,7 @@ SILC_SERVER_CMD_FUNC(cmode)
   SilcBuffer packet, cidp;
   unsigned char *tmp, *tmp_id, *tmp_mask;
   char *cipher = NULL, *hmac = NULL, *passphrase = NULL;
-  SilcUInt32 mode_mask = 0, tmp_len, tmp_len2;
+  SilcUInt32 mode_mask = 0, old_mask = 0, tmp_len, tmp_len2;
   SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   bool set_mask = FALSE;
   SilcPublicKey founder_key = NULL;
@@ -3972,20 +3973,15 @@ SILC_SERVER_CMD_FUNC(cmode)
   if (!tmp_id) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
                                          SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
-    goto out;
+    silc_server_command_free(cmd);
+    return;
   }
   channel_id = silc_id_payload_parse_id(tmp_id, tmp_len2, NULL);
   if (!channel_id) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
                                          SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
-    goto out;
-  }
-
-  /* Get the channel mode mask */
-  tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
-  if (tmp_mask) {
-    SILC_GET32_MSB(mode_mask, tmp_mask);
-    set_mask = TRUE;
+    silc_server_command_free(cmd);
+    return;
   }
 
   /* Get channel entry */
@@ -3998,9 +3994,19 @@ SILC_SERVER_CMD_FUNC(cmode)
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
                                            SILC_STATUS_ERR_NO_SUCH_CHANNEL,
                                            0);
-      goto out;
+      silc_free(channel_id);
+      silc_server_command_free(cmd);
+      return;
     }
   }
+  old_mask = channel->mode;
+
+  /* Get the channel mode mask */
+  tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+  if (tmp_mask) {
+    SILC_GET32_MSB(mode_mask, tmp_mask);
+    set_mask = TRUE;
+  }
 
   /* Check whether this client is on the channel */
   if (!silc_server_client_on_channel(client, channel, &chl)) {
@@ -4284,6 +4290,8 @@ SILC_SERVER_CMD_FUNC(cmode)
          silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
                                                SILC_STATUS_ERR_AUTH_FAILED,
                                                0);
+         silc_pkcs_public_key_free(channel->founder_key);
+         channel->founder_key = NULL;
          goto out;
         }
       }
@@ -4299,7 +4307,7 @@ SILC_SERVER_CMD_FUNC(cmode)
   }
 
   /* Finally, set the mode */
-  channel->mode = mode_mask;
+  old_mask = channel->mode = mode_mask;
 
   /* Send CMODE_CHANGE notify. */
   cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
@@ -4331,6 +4339,7 @@ SILC_SERVER_CMD_FUNC(cmode)
   silc_buffer_free(cidp);
 
  out:
+  channel->mode = old_mask;
   silc_free(fkey);
   silc_free(channel_id);
   silc_server_command_free(cmd);
@@ -4921,7 +4930,7 @@ SILC_SERVER_CMD_FUNC(oper)
   client->mode |= SILC_UMODE_SERVER_OPERATOR;
 
   /* Update statistics */
-  if (client->connection)
+  if (SILC_IS_LOCAL(client))
     server->stat.my_server_ops++;
   if (server->server_type == SILC_ROUTER)
     server->stat.server_ops++;
@@ -5010,6 +5019,11 @@ SILC_SERVER_CMD_FUNC(detach)
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_DETACH, cmd, 0, 0);
 
+  /* Remove operator privileges, since the client may resume in some
+     other server which to it does not have operator privileges. */
+  SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
+  SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+
   /* Send the user mode notify to notify that client is detached */
   client->mode |= SILC_UMODE_DETACHED;
   client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
@@ -5307,7 +5321,7 @@ SILC_SERVER_CMD_FUNC(silcoper)
   client->mode |= SILC_UMODE_ROUTER_OPERATOR;
 
   /* Update statistics */
-  if (client->connection)
+  if (SILC_IS_LOCAL(client))
     server->stat.my_router_ops++;
   if (server->server_type == SILC_ROUTER)
     server->stat.router_ops++;
@@ -5631,7 +5645,8 @@ SILC_SERVER_CMD_FUNC(users)
        && !silc_server_client_on_channel(cmd->sock->user_data, channel, 
                                          NULL)) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
-                                           SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
+                                           SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+                                           0);
       goto out;
     }
   }