Fixed a permission bug
This commit is contained in:
		
							parent
							
								
									3e88ae46b6
								
							
						
					
					
						commit
						ca00f690fd
					
				@ -1 +1 @@
 | 
				
			|||||||
Subproject commit f8b26854fc9eb8fed8ccb30ddcf2379cefaac96c
 | 
					Subproject commit 6fa26411e7f38d5697269262bab68c307bd159b1
 | 
				
			||||||
@ -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());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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 */
 | 
				
			||||||
 | 
				
			|||||||
@ -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)) {
 | 
				
			||||||
 | 
				
			|||||||
@ -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();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user