コード例 #1
0
ファイル: TimeZone.cpp プロジェクト: FirebirdSQL/firebird
TimeZoneSnapshot::TimeZoneSnapshot(thread_db* tdbb, MemoryPool& pool)
	: SnapshotData(pool)
{
	RecordBuffer* tzBuffer = allocBuffer(tdbb, pool, rel_time_zones);
	Record* tzRecord = tzBuffer->getTempRecord();
	tzRecord->nullify();

	TimeZoneUtil::iterateRegions(
		[=]
		(USHORT id, const char* name)
		{
			SINT64 idValue = id;

			putField(tdbb, tzRecord, DumpField(f_tz_id, VALUE_INTEGER, sizeof(idValue), &idValue));
			putField(tdbb, tzRecord, DumpField(f_tz_name, VALUE_STRING, static_cast<USHORT>(strlen(name)), name));
			tzBuffer->store(tzRecord);
		}
	);
}
コード例 #2
0
ファイル: DbCreators.cpp プロジェクト: Salmista-94/firebird
RecordBuffer* DbCreatorsList::getList(thread_db* tdbb, jrd_rel* relation)
{
	fb_assert(relation);
	fb_assert(relation->rel_id == rel_sec_db_creators);

	RecordBuffer* buffer = getData(relation);
	if (buffer)
	{
		return buffer;
	}

	RefPtr<IAttachment> att;
	RefPtr<ITransaction> tra;
	const char* dbName = tdbb->getDatabase()->dbb_config->getSecurityDatabase();
	if (!openDb(dbName, att, tra))
	{
		// In embedded mode we are not raising any errors - silent return
		if (MasterInterfacePtr()->serverMode(-1) < 0)
			return makeBuffer(tdbb);

		(Arg::Gds(isc_crdb_nodb) << dbName).raise();
	}

	Message gr;
	Field<ISC_SHORT> uType(gr);
	Field<Varying> u(gr, MAX_SQL_IDENTIFIER_LEN);

	FbLocalStatus st;
	RefPtr<IResultSet> curs(att->openCursor(&st, tra, 0,
		"select RDB$USER_TYPE, RDB$USER from RDB$DB_CREATORS",
		SQL_DIALECT_V6, NULL, NULL, gr.getMetadata(), NULL, 0));

	if (st->getState() & IStatus::STATE_ERRORS)
	{
		if (!fb_utils::containsErrorCode(st->getErrors(), isc_dsql_relation_err))
			check("IAttachment::openCursor", &st);

		// isc_dsql_relation_err when opening cursor - i.e. table
		// is missing due to non-FB3 security DB

		// In embedded mode we are not raising any errors - silent return
		if (MasterInterfacePtr()->serverMode(-1) < 0)
			return makeBuffer(tdbb);

		(Arg::Gds(isc_crdb_notable) << dbName).raise();
	}

	try
	{
		buffer = makeBuffer(tdbb);
		while (curs->fetchNext(&st, gr.getBuffer()) == IStatus::RESULT_OK)
		{
			Record* record = buffer->getTempRecord();
			record->nullify();

			putField(tdbb, record,
					 DumpField(f_sec_crt_user, VALUE_STRING, u->len, u->data));

			SINT64 v = uType;
			putField(tdbb, record,
					 DumpField(f_sec_crt_u_type, VALUE_INTEGER, sizeof(v), &v));

			buffer->store(record);
		}
		check("IResultSet::fetchNext", &st);
	}
	catch (const Exception&)
	{
		clearSnapshot();
		throw;
	}

	return getData(relation);
}
コード例 #3
0
ファイル: UserManagement.cpp プロジェクト: mp-lee/core
void UserManagement::list(IUser* u, unsigned cachePosition)
{
	RecordBuffer* buffer = getData(rel_sec_users);
	Record* record = buffer->getTempRecord();
	record->nullify();

	const MetaName& plugName(managers[cachePosition].first);
	putField(threadDbb, record,
			 DumpField(f_sec_plugin, VALUE_STRING, static_cast<USHORT>(plugName.length()), plugName.c_str()));

	bool su = false;

	if (u->userName()->entered())
	{
		const char* uname = u->userName()->get();
		putField(threadDbb, record,
				 DumpField(f_sec_user_name, VALUE_STRING, static_cast<USHORT>(strlen(uname)), uname));
		su = strcmp(uname, SYSDBA_USER_NAME) == 0;
	}

	if (u->firstName()->entered())
	{
		putField(threadDbb, record,
				 DumpField(f_sec_first_name, VALUE_STRING, static_cast<USHORT>(strlen(u->firstName()->get())), u->firstName()->get()));
	}

	if (u->middleName()->entered())
	{
		putField(threadDbb, record,
				 DumpField(f_sec_middle_name, VALUE_STRING, static_cast<USHORT>(strlen(u->middleName()->get())), u->middleName()->get()));
	}

	if (u->lastName()->entered())
	{
		putField(threadDbb, record,
				 DumpField(f_sec_last_name, VALUE_STRING, static_cast<USHORT>(strlen(u->lastName()->get())), u->lastName()->get()));
	}

	if (u->active()->entered())
	{
		UCHAR v = u->active()->get() ? '\1' : '\0';
		putField(threadDbb, record,
				 DumpField(f_sec_active, VALUE_BOOLEAN, sizeof(v), &v));
	}

	if (su || u->admin()->entered())
	{
		UCHAR v = (su || u->admin()->get()) ? '\1' : '\0';
		putField(threadDbb, record,
				 DumpField(f_sec_admin, VALUE_BOOLEAN, sizeof(v), &v));
	}

	if (u->comment()->entered())
	{
		putField(threadDbb, record,
				 DumpField(f_sec_comment, VALUE_STRING, static_cast<USHORT>(strlen(u->comment()->get())), u->comment()->get()));
	}

	buffer->store(record);

	if (u->userName()->entered() && u->attributes()->entered())
	{
		buffer = getData(rel_sec_user_attributes);

		ConfigFile cf(ConfigFile::USE_TEXT, u->attributes()->get(), ConfigFile::NO_COMMENTS);
		ConfigFile::Parameters::const_iterator e(cf.getParameters().end());
		for (ConfigFile::Parameters::const_iterator b(cf.getParameters().begin()); b != e; ++b)
		{
			record = buffer->getTempRecord();
			record->nullify();

			putField(threadDbb, record,
					 DumpField(f_sec_attr_user, VALUE_STRING, static_cast<USHORT>(strlen(u->userName()->get())), u->userName()->get()));

			putField(threadDbb, record,
					 DumpField(f_sec_attr_key, VALUE_STRING, b->name.length(), b->name.c_str()));

			putField(threadDbb, record,
					 DumpField(f_sec_attr_value, VALUE_STRING, b->value.length(), b->value.c_str()));

			buffer->store(record);
		}
	}
}
コード例 #4
0
ファイル: Monitoring.cpp プロジェクト: RAvenGEr/opencvr
MonitoringSnapshot::MonitoringSnapshot(thread_db* tdbb, MemoryPool& pool)
	: SnapshotData(pool)
{
	SET_TDBB(tdbb);

	PAG_header(tdbb, true);

	Database* const dbb = tdbb->getDatabase();
	fb_assert(dbb);

	Attachment* const attachment = tdbb->getAttachment();
	fb_assert(attachment);

	const AttNumber self_att_id = attachment->att_attachment_id;

	// Initialize record buffers
	RecordBuffer* const dbb_buffer = allocBuffer(tdbb, pool, rel_mon_database);
	RecordBuffer* const att_buffer = allocBuffer(tdbb, pool, rel_mon_attachments);
	RecordBuffer* const tra_buffer = allocBuffer(tdbb, pool, rel_mon_transactions);
	RecordBuffer* const stmt_buffer = allocBuffer(tdbb, pool, rel_mon_statements);
	RecordBuffer* const call_buffer = allocBuffer(tdbb, pool, rel_mon_calls);
	RecordBuffer* const io_stat_buffer = allocBuffer(tdbb, pool, rel_mon_io_stats);
	RecordBuffer* const rec_stat_buffer = allocBuffer(tdbb, pool, rel_mon_rec_stats);
	RecordBuffer* const ctx_var_buffer = allocBuffer(tdbb, pool, rel_mon_ctx_vars);
	RecordBuffer* const mem_usage_buffer = allocBuffer(tdbb, pool, rel_mon_mem_usage);
	RecordBuffer* const tab_stat_buffer = allocBuffer(tdbb, pool, rel_mon_tab_stats);

	// Dump our own data and downgrade the lock, if required

	Monitoring::dumpAttachment(tdbb, attachment);

	if (!(attachment->att_flags & ATT_monitor_done))
	{
		LCK_convert(tdbb, attachment->att_monitor_lock, LCK_SR, LCK_NO_WAIT);
		attachment->att_flags |= ATT_monitor_done;
	}

	// Enumerate active sessions

	const string& user_name = attachment->att_user->usr_user_name;
	const bool locksmith = attachment->locksmith();
	const char* user_name_ptr = locksmith ? NULL : user_name.c_str();

	MonitoringData::SessionList sessions(pool);

	Lock temp_lock(tdbb, sizeof(AttNumber), LCK_monitor), *lock = &temp_lock;

	{ // scope for the guard

		MonitoringData::Guard guard(dbb->dbb_monitoring_data);
		dbb->dbb_monitoring_data->enumerate(sessions, user_name_ptr);
	}

	// Signal other sessions to dump their state

	{ // scope for the temporary status

		ThreadStatusGuard temp_status(tdbb);

		for (AttNumber* iter = sessions.begin(); iter != sessions.end(); iter++)
		{
			if (*iter != self_att_id)
			{
				lock->lck_key.lck_long = *iter;

				if (LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT))
					LCK_release(tdbb, lock);
			}
		}
	}

	// Collect monitoring data. Start by gathering database-level info,
	// it goes directly to the temporary space (as it's not stored in the shared dump).

	TempSpace temp_space(pool, SCRATCH);

	{ // scope for putDatabase and its utilities

		TempWriter writer(temp_space);
		SnapshotData::DumpRecord tempRecord(pool, writer);

		Monitoring::putDatabase(tdbb, tempRecord);
	}

	// Read the dump into a temporary space. While being there,
	// also check for dead sessions and garbage collect them.

	{ // scope for the guard

		MonitoringData::Guard guard(dbb->dbb_monitoring_data);

		ThreadStatusGuard temp_status(tdbb);
		lock->lck_type = LCK_attachment;

		for (AttNumber* iter = sessions.begin(); iter != sessions.end(); iter++)
		{
			if (*iter != self_att_id)
			{
				lock->lck_key.lck_long = *iter;

				if (LCK_lock(tdbb, lock, LCK_EX, LCK_NO_WAIT))
				{
					LCK_release(tdbb, lock);
					dbb->dbb_monitoring_data->cleanup(*iter);
				}
			}
		}

		dbb->dbb_monitoring_data->read(user_name_ptr, temp_space);
	}

	// Parse the dump

	MonitoringData::Reader reader(pool, temp_space);

	SnapshotData::DumpRecord dumpRecord(pool);
	while (reader.getRecord(dumpRecord))
	{
		const int rid = dumpRecord.getRelationId();

		RecordBuffer* buffer = NULL;
		Record* record = NULL;

		switch (rid)
		{
		case rel_mon_database:
			buffer = dbb_buffer;
			break;
		case rel_mon_attachments:
			buffer = att_buffer;
			break;
		case rel_mon_transactions:
			buffer = tra_buffer;
			break;
		case rel_mon_statements:
			buffer = stmt_buffer;
			break;
		case rel_mon_calls:
			buffer = call_buffer;
			break;
		case rel_mon_io_stats:
			buffer = io_stat_buffer;
			break;
		case rel_mon_rec_stats:
			buffer = rec_stat_buffer;
			break;
		case rel_mon_ctx_vars:
			buffer = ctx_var_buffer;
			break;
		case rel_mon_mem_usage:
			buffer = mem_usage_buffer;
			break;
		case rel_mon_tab_stats:
			buffer = tab_stat_buffer;
			break;
		default:
			fb_assert(false);
		}

		if (buffer)
		{
			record = buffer->getTempRecord();
			record->nullify();
		}

		bool store_record = false;

		SnapshotData::DumpField dumpField;
		while (dumpRecord.getField(dumpField))
		{
			if (record)
			{
				putField(tdbb, record, dumpField);
				store_record = true;
			}
		}

		if (store_record)
			buffer->store(record);
	}
}