Fixed a permission bug

This commit is contained in:
WolverinDEV 2019-11-09 18:53:53 +01:00
parent 3e88ae46b6
commit ca00f690fd
7 changed files with 49 additions and 22 deletions

@ -1 +1 @@
Subproject commit f8b26854fc9eb8fed8ccb30ddcf2379cefaac96c Subproject commit 6fa26411e7f38d5697269262bab68c307bd159b1

View File

@ -308,7 +308,7 @@ int main(int argc, char** argv) {
logMessage(LOG_GENERAL, "Starting music providers"); logMessage(LOG_GENERAL, "Starting music providers");
terminal::instance()->setPrompt("§aStarting server. §7[§aloading music§7]"); terminal::instance()->setPrompt("§aStarting server. §7[§aloading music§7]");
if(ts::config::music::enabled && !arguments.cmdOptionExists("--valgrind")) { if(ts::config::music::enabled && !arguments.cmdOptionExists("--no-providers")) {
::music::manager::loadProviders("providers"); ::music::manager::loadProviders("providers");
::music::manager::register_provider(::music::provider::ChannelProvider::create_provider()); ::music::manager::register_provider(::music::provider::ChannelProvider::create_provider());
} }

View File

@ -1016,6 +1016,12 @@ deque<pair<ts::permission::PermissionType, ts::permission::PermissionValue>> TSS
return result; return result;
} }
permission::v2::PermissionFlaggedValue TSServer::calculatePermission2(ts::permission::PermissionType permission, ts::ClientDbId cldbid, ts::server::ClientType type, ts::ChannelId channel, std::shared_ptr<CalculateCache> cache) {
auto result = this->calculatePermissions2(cldbid, {permission}, type, channel, false, cache);
if(result.empty()) return {permNotGranted, false};
return result.front().second;
}
ts::permission::PermissionValue TSServer::calculatePermission(permission::PermissionTestType test, ClientDbId cldbid, permission::PermissionType permission, ClientType client_type, const std::shared_ptr<BasicChannel>& channel, std::shared_ptr<CalculateCache> cache) { ts::permission::PermissionValue TSServer::calculatePermission(permission::PermissionTestType test, ClientDbId cldbid, permission::PermissionType permission, ClientType client_type, const std::shared_ptr<BasicChannel>& channel, std::shared_ptr<CalculateCache> cache) {
auto result = this->calculatePermissions(test, cldbid, {permission}, client_type, channel, cache); auto result = this->calculatePermissions(test, cldbid, {permission}, client_type, channel, cache);
if(result.empty()) return permNotGranted; if(result.empty()) return permNotGranted;

View File

@ -225,6 +225,9 @@ namespace ts {
std::shared_ptr<CalculateCache> cache = nullptr /* calculate cache */); std::shared_ptr<CalculateCache> cache = nullptr /* calculate cache */);
permission::PermissionValue calculatePermission(permission::PermissionTestType, ClientDbId, permission::PermissionType, ClientType type, const std::shared_ptr<BasicChannel>& channel, std::shared_ptr<CalculateCache> cache = nullptr); permission::PermissionValue calculatePermission(permission::PermissionTestType, ClientDbId, permission::PermissionType, ClientType type, const std::shared_ptr<BasicChannel>& channel, std::shared_ptr<CalculateCache> cache = nullptr);
permission::v2::PermissionFlaggedValue calculatePermission2(permission::PermissionType, ClientDbId, ClientType type, ChannelId channel, std::shared_ptr<CalculateCache> cache = nullptr);
permission::PermissionValue calculatePermissionGrant(permission::PermissionTestType, ClientDbId, permission::PermissionType, ClientType type, const std::shared_ptr<BasicChannel>& channel); permission::PermissionValue calculatePermissionGrant(permission::PermissionTestType, ClientDbId, permission::PermissionType, ClientType type, const std::shared_ptr<BasicChannel>& channel);
bool verifyServerPassword(std::string, bool hashed = false); bool verifyServerPassword(std::string, bool hashed = false);

View File

@ -3426,46 +3426,57 @@ CommandResult ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd)
CMD_CHK_AND_INC_FLOOD_POINTS(25); CMD_CHK_AND_INC_FLOOD_POINTS(25);
auto serverGroup = this->server->groups->findGroup(cmd["cgid"].as<GroupId>()); auto serverGroup = this->server->groups->findGroup(cmd["cgid"].as<GroupId>());
if (!serverGroup && cmd["gcid"].as<GroupId>() == 0) if (!serverGroup && cmd["cgid"].as<GroupId>() == 0)
serverGroup = this->server->groups->defaultGroup(GroupTarget::GROUPTARGET_CHANNEL); serverGroup = this->server->groups->defaultGroup(GroupTarget::GROUPTARGET_CHANNEL);
if (!serverGroup || serverGroup->target() != GROUPTARGET_CHANNEL) if (!serverGroup || serverGroup->target() != GROUPTARGET_CHANNEL)
return {findError("parameter_invalid"), "invalid channel group id"}; return {findError("parameter_invalid"), "invalid channel group id"};
shared_lock server_channel_lock(this->server->channel_tree_lock); /* ensure we dont get moved or somebody could move us */ shared_lock server_channel_lock(this->server->channel_tree_lock); /* ensure we dont get moved or somebody could move us */
std::shared_ptr<BasicChannel> channel = this->server->channelTree->findChannel(cmd["cid"].as<ChannelId>()); auto channel_id = cmd["cid"].as<ChannelId>();
auto channel = this->server->channelTree->findChannel(channel_id);
if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"};
auto target_cldbid = cmd["cldbid"].as<ClientDbId>(); auto target_cldbid = cmd["cldbid"].as<ClientDbId>();
{ {
auto channel_group_member_add_power = this->calculate_permission_value(permission::i_channel_group_member_add_power, channel_id);
if(!serverGroup->permission_granted(permission::i_channel_group_member_add_power, this->calculate_permission_value(permission::i_channel_group_member_add_power, -1), true)) { if(!serverGroup->permission_granted(permission::i_channel_group_needed_member_add_power, channel_group_member_add_power, true)) {
if(target_cldbid != this->getClientDatabaseId()) if(target_cldbid != this->getClientDatabaseId())
return CommandResultPermissionError{permission::i_channel_group_member_add_power}; return CommandResultPermissionError{permission::i_channel_group_member_add_power};
if(!serverGroup->permission_granted(permission::i_channel_group_member_add_power, this->calculate_permission_value(permission::i_channel_group_self_add_power, -1), true))
auto channel_group_self_add_power = this->calculate_permission_value(permission::i_channel_group_self_add_power, channel_id);
if(!serverGroup->permission_granted(permission::i_channel_group_needed_member_add_power, channel_group_self_add_power, true))
return CommandResultPermissionError{permission::i_channel_group_self_add_power}; return CommandResultPermissionError{permission::i_channel_group_self_add_power};
} }
auto needed_client_permission = this->server->calculatePermission(permission::PERMTEST_ORDERED, target_cldbid, permission::i_client_needed_permission_modify_power, ClientType::CLIENT_TEAMSPEAK,nullptr); auto client_permission_modify_power = this->calculate_permission_value(permission::i_client_permission_modify_power, channel_id);
if(needed_client_permission != permNotGranted) { auto client_needed_permission_modify_power = this->server->calculatePermission2(
if(!this->permission_granted(this->permissionValue(permission::i_client_permission_modify_power), needed_client_permission)) permission::i_client_needed_permission_modify_power, target_cldbid, ClientType::CLIENT_TEAMSPEAK, channel_id);
return CommandResultPermissionError{permission::i_client_needed_permission_modify_power};
}
if(client_needed_permission_modify_power.has_value) {
if(!this->permission_granted(client_permission_modify_power, client_needed_permission_modify_power.value, true))
return CommandResultPermissionError{permission::i_client_permission_modify_power};
}
} }
auto oldGroup = this->server->groups->getChannelGroupExact(target_cldbid, channel, false); {
if(oldGroup) { auto old_group = this->server->groups->getChannelGroupExact(target_cldbid, channel, false);
if(!serverGroup->permission_granted(permission::i_channel_group_member_remove_power, this->calculate_permission_value(permission::i_channel_group_member_remove_power, -1), true)) { if(old_group) {
if(target_cldbid != this->getClientDatabaseId()) auto channel_group_member_remove_power = this->calculate_permission_value(permission::i_channel_group_member_remove_power, channel_id);
return CommandResultPermissionError{permission::i_channel_group_member_remove_power}; if(!serverGroup->permission_granted(permission::i_channel_group_needed_member_remove_power, channel_group_member_remove_power, true)) {
if(!serverGroup->permission_granted(permission::i_channel_group_member_remove_power, this->calculate_permission_value(permission::i_channel_group_self_remove_power, -1), true)) if(target_cldbid != this->getClientDatabaseId())
return CommandResultPermissionError{permission::i_channel_group_self_remove_power}; return CommandResultPermissionError{permission::i_channel_group_member_remove_power};
auto channel_group_self_remove_power = this->calculate_permission_value(permission::i_channel_group_self_remove_power, channel_id);
if(!serverGroup->permission_granted(permission::i_channel_group_needed_member_remove_power, channel_group_self_remove_power, true))
return CommandResultPermissionError{permission::i_channel_group_self_remove_power};
}
} }
} }
this->server->groups->setChannelGroup(target_cldbid, serverGroup, channel); this->server->groups->setChannelGroup(target_cldbid, serverGroup, channel);
for (const auto &targetClient : this->server->findClientsByCldbId(target_cldbid)) { for (const auto &targetClient : this->server->findClientsByCldbId(target_cldbid)) {
unique_lock client_channel_lock_w(targetClient->channel_lock); unique_lock client_channel_lock_w(targetClient->channel_lock);
auto updates = this->server->groups->update_server_group_property(targetClient, false, targetClient->getChannel()); /* needs a write lock */ auto updates = this->server->groups->update_server_group_property(targetClient, false, targetClient->getChannel()); /* needs a write lock */

View File

@ -603,6 +603,7 @@ bool VoiceClientConnection::preprocess_write_packets() {
packet = std::move(category.queue.front()); packet = std::move(category.queue.front());
category.queue.pop_front(); category.queue.pop_front();
category.has_work = !category.queue.empty(); category.has_work = !category.queue.empty();
flag_more = category.has_work;
} }
if(!this->prepare_packet_for_write(buffers, packet, work_lock)) { if(!this->prepare_packet_for_write(buffers, packet, work_lock)) {

View File

@ -546,8 +546,14 @@ void VoiceServer::handleMessageWrite(int fd, short events, void *_event_handle)
TIMING_STEP(timings, "retrigger client"); TIMING_STEP(timings, "retrigger client");
} }
if(!more_clients) if(more_clients) {
break; /* allow other clients to write as well */
if(more_to_write)
event_handle->push_voice_write_queue(client);
client.reset();
continue;
}
if(!more_to_prepare) { if(!more_to_prepare) {
/* we're done with this client. Nothing more to prepare */ /* we're done with this client. Nothing more to prepare */
client.reset(); client.reset();