예제 #1
0
void UserManagement::execute(USHORT id)
{
	if (id >= commands.getCount())
	{
		status_exception::raise(Arg::Gds(isc_random) << "Wrong job id passed to UserManagement::execute()");
	}

	if (!commands[id])
		return;	// Already executed

	Auth::UserData* command = commands[id];
	IManagement* manager = getManager(command->plugin.c_str());

	if (!manager)
		return;	// Already commited

	LocalStatus status;
	CheckStatusWrapper statusWrapper(&status);

	if (command->attr.entered() || command->op == Auth::ADDMOD_OPER)
	{
		Auth::StackUserData cmd;
		cmd.op = Auth::DIS_OPER;
		cmd.user.set(&statusWrapper, command->userName()->get());
		check(&statusWrapper);
		cmd.user.setEntered(&statusWrapper, 1);
		check(&statusWrapper);

		OldAttributes oldAttributes;
		int ret = manager->execute(&statusWrapper, &cmd, &oldAttributes);
		if (ret == 0 || status.getErrors()[1] != isc_missing_data_structures)
			checkSecurityResult(ret, &status, command->userName()->get(), command->operation());
		else
			statusWrapper.init();

		if (command->op == Auth::ADDMOD_OPER)
			command->op = oldAttributes.present ? Auth::MOD_OPER : Auth::ADD_OPER;

		if (command->attr.entered())
		{
			ConfigFile ocf(ConfigFile::USE_TEXT, oldAttributes.value.c_str(), ConfigFile::NO_COMMENTS);
			ConfigFile::Parameters::const_iterator old(ocf.getParameters().begin());
			ConfigFile::Parameters::const_iterator oldEnd(ocf.getParameters().end());

			ConfigFile ccf(ConfigFile::USE_TEXT, command->attr.get(), ConfigFile::NO_COMMENTS);
			ConfigFile::Parameters::const_iterator cur(ccf.getParameters().begin());
			ConfigFile::Parameters::const_iterator curEnd(ccf.getParameters().end());

			// Dup check
			ConfigFile::KeyType prev;
			while (cur != curEnd)
			{
				if (cur->name == prev)
					(Arg::Gds(isc_dup_attribute) << cur->name).raise();

				prev = cur->name;
				++cur;
			}
			cur = ccf.getParameters().begin();

			string merged;
			while (old != oldEnd && cur != curEnd)
			{
				if (old->name == cur->name)
				{
					merge(merged, cur);
					++old;
					++cur;
				}
				else if (old->name < cur->name)
				{
					merge(merged, old);
					++old;
				}
				else
				{
					merge(merged, cur);
					++cur;
				}
			}

			while (cur != curEnd)
			{
				merge(merged, cur);
				++cur;
			}

			while (old != oldEnd)
			{
				merge(merged, old);
				++old;
			}

			if (merged.hasData())
			{
				command->attr.set(&statusWrapper, merged.c_str());
				check(&statusWrapper);
			}
			else
			{
				command->attr.setEntered(&statusWrapper, 0);
				check(&statusWrapper);
				command->attr.setSpecified(1);
				command->attr.set(&statusWrapper, "");
				check(&statusWrapper);
			}
		}
	}

	if (command->op == Auth::ADD_OPER)
	{
		if (!command->pass.entered())
			Arg::PrivateDyn(291).raise();

		if (!command->act.entered())
		{
			command->act.set(&statusWrapper, 1);
			check(&statusWrapper);
			command->act.setEntered(&statusWrapper, 1);
			check(&statusWrapper);
		}
	}

	int errcode = manager->execute(&statusWrapper, command, NULL);
	checkSecurityResult(errcode, &status, command->userName()->get(), command->operation());

	delete commands[id];
	commands[id] = NULL;
}