Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2003 Pekka Riikonen
+ Copyright (C) 1997 - 2004 Pekka Riikonen
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
buffer =
silc_command_reply_payload_encode_va(command, status, 0,
silc_command_get_ident(cmd->payload),
- 2, arg_type1, arg1, arg_len2,
+ 2, arg_type1, arg1, arg_len1,
arg_type2, arg2, arg_len2);
silc_server_packet_send(cmd->server, cmd->sock,
SILC_PACKET_COMMAND_REPLY, 0,
/* Check if the ID is in the list already */
silc_hash_table_list(channel->invite_list, &htl);
- while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
+ while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
tmp = NULL;
break;
channel->invite_list)),
SILC_STR_END);
silc_hash_table_list(channel->invite_list, &htl);
- while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2))
+ while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
type);
silc_hash_table_list_reset(&htl);
SilcServer server = app_context;
QuitInternal q = (QuitInternal)context;
- /* Free all client specific data, such as client entry and entires
- on channels this client may be on. */
- silc_server_free_client_data(server, q->sock, q->sock->user_data,
- TRUE, q->signoff);
- q->sock->user_data = NULL;
+ if (q->sock->user_data) {
+ /* Free all client specific data, such as client entry and entires
+ on channels this client may be on. */
+ silc_server_free_client_data(server, q->sock, q->sock->user_data,
+ TRUE, q->signoff);
+ q->sock->user_data = NULL;
+ }
- /* Close the connection on our side */
- silc_server_close_connection(server, q->sock);
+ if (!SILC_IS_DISCONNECTED(q->sock))
+ /* Close the connection on our side */
+ silc_server_close_connection(server, q->sock);
silc_socket_free(q->sock);
silc_free(q->signoff);
if (!strchr(client->nickname, '@')) {
silc_strncat(check2, sizeof(check2), "@", 1);
silc_strncat(check2, sizeof(check2),
- server->server_name, strlen(server->server_name));
+ SILC_IS_LOCAL(client) ? server->server_name :
+ client->router->server_name,
+ SILC_IS_LOCAL(client) ? strlen(server->server_name) :
+ strlen(client->router->server_name));
}
silc_strncat(check2, sizeof(check2), "!", 1);
silc_strncat(check2, sizeof(check2),
cmd->sock->hostname, strlen(cmd->sock->hostname));
}
+ SILC_LOG_DEBUG(("check : %s", check));
+ SILC_LOG_DEBUG(("check2: %s", check2));
+
/* Check invite list if channel is invite-only channel */
if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
if (!channel->invite_list ||
if (!passphrase || !channel->passphrase ||
memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_BAD_PASSWORD, 0);
+ chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+ silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
+ SILC_STATUS_ERR_BAD_PASSWORD, 0,
+ 2, chidp->data, chidp->len);
+ silc_buffer_free(chidp);
goto out;
}
}
SILC_STR_END);
silc_hash_table_list(channel->invite_list, &htl);
- while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply))
+ while (silc_hash_table_get(&htl, (void *)&tmp_len, (void *)&reply))
invite_list = silc_argument_payload_encode_one(invite_list,
reply->data,
reply->len, tmp_len);
SILC_STR_END);
silc_hash_table_list(channel->ban_list, &htl);
- while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply))
+ while (silc_hash_table_get(&htl, (void *)&tmp_len, (void *)&reply))
ban_list = silc_argument_payload_encode_one(ban_list,
reply->data,
reply->len, tmp_len);
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
SILC_STATUS_OK, 0,
ident, 2,
- 2, idp, idp->len,
+ 2, idp->data, idp->len,
3, motd, motd_len);
} else {
/* No motd */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
SILC_STATUS_OK, 0,
ident, 1,
- 2, idp, idp->len);
+ 2, idp->data, idp->len);
}
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
goto out;
}
- if (!entry && !cmd->pending && !server->standalone) {
+ /* Send to primary router only if we don't know the server
+ * the client requested or if the server is not locally connected */
+ if ((!entry || !(entry->data.status & SILC_IDLIST_STATUS_LOCAL))
+ && !cmd->pending && !server->standalone) {
/* Send to the primary router */
SilcBuffer tmpbuf;
SilcUInt16 old_ident;
goto out;
}
- idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
+ idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
SILC_STATUS_OK, 0, ident, 2,
- 2, idp, idp->len,
+ 2, idp->data, idp->len,
3, entry->motd,
entry->motd ?
strlen(entry->motd) : 0);
}
/* Anonymous mode cannot be set by client */
- if (mask & SILC_UMODE_ANONYMOUS) {
- if (!(client->mode & SILC_UMODE_ANONYMOUS)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED, 0);
- goto out;
- }
- } else {
- if (client->mode & SILC_UMODE_ANONYMOUS) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED, 0);
- goto out;
- }
+ if (mask & SILC_UMODE_ANONYMOUS &&
+ !(client->mode & SILC_UMODE_ANONYMOUS)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+ SILC_STATUS_ERR_PERM_DENIED, 0);
+ goto out;
}
/* Update statistics */
server->stat.my_aways--;
}
+ /* If the client has anonymous mode set, preserve it. */
+ if (client->mode & SILC_UMODE_ANONYMOUS)
+ mask |= SILC_UMODE_ANONYMOUS;
+
/* Change the mode */
client->mode = mask;
channel->founder_key = NULL;
goto out;
}
- has_founder:
}
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
}
}
}
+ has_founder:
if (mode_mask & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, st, 0);
goto out;
}
- has_pk_list:
}
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
}
}
}
+ has_pk_list:
/* Finally, set the mode */
old_mask = channel->mode = mode_mask;
/* Get target client's entry */
target_client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, NULL);
- if (!target_client) {
+ if (!target_client)
target_client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
- }
if (target_client != client &&
!(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
!(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0,
+ SILC_STATUS_ERR_NOT_YOU, 0,
2, tmp_ch_id, tmp_ch_len);
goto out;
}
if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
if (target_client != client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU, 0);
+ SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
+ 0);
goto out;
}
}
/* There cannot be anyone else as founder on the channel now. This
- client is definitely the founder due to this authentication */
- silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
- if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
- chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
- silc_server_force_cumode_change(server, NULL, channel, chl2,
- chl2->mode);
- break;
- }
- silc_hash_table_list_reset(&htl);
+ client is definitely the founder due to this authentication. This
+ is done only on router, not on server, since server cannot know
+ whether router will accept this mode change or not. XXX This
+ probably shouldn't be done anymore at all, may cause problems in
+ router-router connections too (maybe just AUTH_FAILED error should
+ be returned). -Pekka */
+ if (server->server_type == SILC_ROUTER) {
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+ if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+ silc_server_force_cumode_change(server, NULL, channel, chl2,
+ chl2->mode);
+ break;
+ }
+ silc_hash_table_list_reset(&htl);
+ }
sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
}
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
- /* Send command reply to sender */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_OK, 0);
-
/* Send KICKED notify to local clients on the channel */
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
/* Get the nickname from the watcher list and use the same key in
new entries as well. If key doesn't exist then create it. */
- if (!silc_hash_table_find(server->watcher_list, hash, (void **)&tmp, NULL))
+ if (!silc_hash_table_find(server->watcher_list, hash, (void *)&tmp, NULL))
tmp = silc_memdup(hash, CLIENTID_HASH_LEN);
/* Add the client to the watcher list with the specified nickname hash. */
/* Check that this client is watching for this nickname */
if (!silc_hash_table_find_by_context(server->watcher_list, hash,
- client, (void **)&tmp)) {
+ client, (void *)&tmp)) {
/* Nickname is alredy being watched for this client */
silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
SILC_STATUS_ERR_NO_SUCH_NICK, 0,
channel->ban_list)),
SILC_STR_END);
silc_hash_table_list(channel->ban_list, &htl);
- while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2))
+ while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
type);
silc_hash_table_list_reset(&htl);