Example #1
0
	void grantRevokeAdmin(Firebird::IUser* user, bool ignoreRevoke = false)
	{
		if (!user->admin()->entered())
		{
			return;
		}

		Firebird::LocalStatus s;
		Firebird::CheckStatusWrapper statusWrapper(&s);

		Firebird::string userName(user->userName()->get());
		prepareName(userName, '"');

		Firebird::string sql;
		if (user->admin()->get() == 0)
		{
			Firebird::string userName2(user->userName()->get());
			prepareName(userName2, '\'');
			Firebird::string selGrantor;
			selGrantor.printf("SELECT RDB$GRANTOR FROM RDB$USER_PRIVILEGES "
				"WHERE RDB$USER = '******' AND RDB$RELATION_NAME = '%s' AND RDB$PRIVILEGE = 'M'",
				userName2.c_str(), ADMIN_ROLE);
			Message out;
			Field<Varying> grantor(out, MAX_SQL_IDENTIFIER_SIZE);
			Firebird::IResultSet* curs = att->openCursor(&statusWrapper, tra, selGrantor.length(),
				selGrantor.c_str(), SQL_DIALECT_V6, NULL, NULL, out.getMetadata(), NULL, 0);
			check(&statusWrapper);

			bool hasGrant = curs->fetchNext(&statusWrapper, out.getBuffer()) == Firebird::IStatus::RESULT_OK;
			curs->close(&statusWrapper);
			check(&statusWrapper);

			if (hasGrant)
			{
				selGrantor = grantor;
				prepareName(selGrantor, '"');

				sql.printf("REVOKE %s FROM \"%s\" GRANTED BY \"%s\"",
					ADMIN_ROLE, userName.c_str(), selGrantor.c_str());
			}
			else
			{
				if (ignoreRevoke)
					return;

				// no grant - let engine produce correct error message
				sql.printf("REVOKE %s FROM \"%s\"", ADMIN_ROLE, userName.c_str());
			}
		}
		else
		{
			sql.printf("GRANT %s TO \"%s\"", ADMIN_ROLE, userName.c_str());
		}

		att->execute(&statusWrapper, tra, sql.length(), sql.c_str(),
			SQL_DIALECT_V6, NULL, NULL, NULL, NULL);
		check(&statusWrapper);
	}
Example #2
0
static void alice_output(bool error, const SCHAR* format, ...)
{

	AliceGlobals* tdgbl = AliceGlobals::getSpecific();

	va_list arglist;
	va_start(arglist, format);
	Firebird::string buf;
	buf.vprintf(format, arglist);
	va_end(arglist);

	if (error)
		tdgbl->uSvc->outputError(buf.c_str());
	else
		tdgbl->uSvc->outputVerbose(buf.c_str());
}
Example #3
0
ModuleLoader::Module* ModuleLoader::loadModule(ISC_STATUS* status, const Firebird::PathName& modPath)
{
	void* module = dlopen(modPath.nullStr(), FB_RTLD_MODE);
	if (module == NULL)
	{
		if (status)
		{
			status[0] = isc_arg_gds;
			status[1] = isc_random;
			status[2] = isc_arg_string;
			status[3] = (ISC_STATUS) dlerror();
			status[4] = isc_arg_end;
		}

		return 0;
	}

#ifdef DEBUG_THREAD_IN_UNLOADED_LIBRARY
	Firebird::string command;
	command.printf("echo +++ %s +++ >>/tmp/fbmaps;date >> /tmp/fbmaps;cat /proc/%d/maps >>/tmp/fbmaps",
		modPath.c_str(), getpid());
	system(command.c_str());
#endif

	return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(*getDefaultMemoryPool(), modPath, module);
}
Example #4
0
void PreparedStatement::init(thread_db* tdbb, Attachment* attachment, jrd_tra* transaction,
	const Firebird::string& text, bool isInternalRequest)
{
	AutoSetRestore<SSHORT> autoAttCharset(&attachment->att_charset,
		(isInternalRequest ? CS_METADATA : attachment->att_charset));

	request = NULL;
	try
	{
		const Database& dbb = *tdbb->getDatabase();
		const int dialect = isInternalRequest || (dbb.dbb_flags & DBB_DB_SQL_dialect_3) ?
			SQL_DIALECT_V6 : SQL_DIALECT_V5;

		request = DSQL_prepare(tdbb, attachment, transaction, text.length(), text.c_str(), dialect,
			NULL, NULL, isInternalRequest);

		const DsqlCompiledStatement* statement = request->getStatement();

		if (statement->getSendMsg())
			parseDsqlMessage(statement->getSendMsg(), inValues, inMetadata, inMessage);

		if (statement->getReceiveMsg())
			parseDsqlMessage(statement->getReceiveMsg(), outValues, outMetadata, outMessage);
	}
	catch (const Exception&)
	{
		if (request)
		{
			DSQL_free_statement(tdbb, request, DSQL_drop);
		}
		throw;
	}
}
Example #5
0
bool readenv(const char* env_name, Firebird::PathName& env_value)
{
	Firebird::string result;
	bool rc = readenv(env_name, result);
	env_value.assign(result.c_str(), result.length());
	return rc;
}
Example #6
0
TracePlugin* FB_CARG TraceFactoryImpl::trace_create(Firebird::IStatus* status, TraceInitInfo* initInfo)
{
	Firebird::MasterInterfacePtr master;
	const char* dbname = NULL;
	try
	{
		master->upgradeInterface(initInfo, FB_TRACE_INIT_INFO_VERSION, upInfo);

		dbname = initInfo->getDatabaseName();
		if (!dbname)
			dbname = "";

		TracePluginConfig config;
		TraceCfgReader::readTraceConfiguration(initInfo->getConfigText(), dbname, config);

		TraceDatabaseConnection* connection = initInfo->getConnection();
		if (connection)
			master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);

		if (!config.enabled ||
			(config.connection_id && connection &&
				(connection->getConnectionID() != SLONG(config.connection_id))))
		{
			return NULL; // Plugin is not needed, no error happened.
		}

		Firebird::AutoPtr<TraceLogWriter, Firebird::SimpleRelease<TraceLogWriter> >
			logWriter(initInfo->getLogWriter());

		if (logWriter)
			config.log_filename = "";

		return new TracePluginImpl(config, initInfo);	// Everything is ok, we created a plugin

	}
	catch (Firebird::Exception& ex)
	{
		// put error into trace log
		TraceLogWriter* logWriter = initInfo->getLogWriter();
		if (logWriter)
		{
			master->upgradeInterface(logWriter, FB_TRACE_LOG_WRITER_VERSION, upInfo);
			const char* strEx = TracePluginImpl::marshal_exception(ex);
			Firebird::string err;
			if (dbname)
				err.printf("Error creating trace session for database \"%s\":\n%s\n", dbname, strEx);
			else
				err.printf("Error creating trace session for service manager attachment:\n%s\n", strEx);

			logWriter->write(err.c_str(), err.length());
			logWriter->release();
		}
		else
			ex.stuffException(status);
	}

	return NULL;
}
void ExecuteStatement::open(thread_db* tdbb, jrd_nod* sql, SSHORT nVars, bool singleton)
{
    SET_TDBB(tdbb);

    Attachment* const attachment = tdbb->getAttachment();
    jrd_tra* transaction = tdbb->getTransaction();

    if (transaction->tra_callback_count >= MAX_CALLBACKS)
    {
        ERR_post(Arg::Gds(isc_exec_sql_max_call_exceeded));
    }

    varCount = nVars;
    singleMode = singleton;

    Firebird::string sqlText;
    getString(tdbb, sqlText, EVL_expr(tdbb, sql), tdbb->getRequest());
    memcpy(startOfSqlOperator, sqlText.c_str(), sizeof(startOfSqlOperator) - 1);
    startOfSqlOperator[sizeof(startOfSqlOperator) - 1] = 0;

    transaction->tra_callback_count++;

    try
    {
        stmt = attachment->prepareStatement(tdbb, *tdbb->getDefaultPool(), transaction, sqlText);

        if (stmt->getResultCount() == 0)
        {
            delete stmt;
            stmt = NULL;

            ERR_post(Arg::Gds(isc_exec_sql_invalid_req) << Arg::Str(startOfSqlOperator));
        }

        if (stmt->getResultCount() != varCount)
        {
            delete stmt;
            stmt = NULL;

            ERR_post(Arg::Gds(isc_wronumarg));
        }

        resultSet = stmt->executeQuery(tdbb, transaction);

        fb_assert(transaction == tdbb->getTransaction());
    }
    catch (const Firebird::Exception&)
    {
        transaction->tra_callback_count--;
        throw;
    }

    transaction->tra_callback_count--;
}
Example #8
0
void Stream::format(const char *pattern, ...)
{
	Firebird::string temp;

	va_list		args;
	va_start	(args, pattern);
	temp.vprintf(pattern, args);
	va_end(args);

	putSegment (temp.c_str());
}
Example #9
0
void* DlfcnModule::findSymbol(const Firebird::string& symName)
{
	void* result = dlsym(module, symName.c_str());
	if (result == NULL)
	{
		Firebird::string newSym ='_' + symName;
		result = dlsym(module, newSym.c_str());
	}
	return result;

}
Example #10
0
void iscDbLogStatus(const TEXT* text, Firebird::IStatus* status)
{
	const TEXT* hdr = NULL;
	Firebird::string buf;
	if (text)
	{
		buf = "Database: ";
		buf += text;
		hdr = buf.c_str();
	}
	iscLogStatus(hdr, status);
}
Example #11
0
// create directory for lock files and set appropriate access rights
void createLockDirectory(const char* pathname)
{
	static bool errorLogged = false;

	DWORD attr = GetFileAttributes(pathname);
	DWORD errcode = 0;
	if (attr == INVALID_FILE_ATTRIBUTES)
	{
		errcode = GetLastError();
		if (errcode == ERROR_FILE_NOT_FOUND)
		{
			if (!CreateDirectory(pathname, NULL)) {
				errcode = GetLastError();
			}
			else
			{
				adjustLockDirectoryAccess(pathname);

				attr = GetFileAttributes(pathname);
				if (attr == INVALID_FILE_ATTRIBUTES) {
					errcode = GetLastError();
				}
			}
		}
	}

	Firebird::string err;
	if (attr == INVALID_FILE_ATTRIBUTES)
	{
		err.printf("Can't create directory \"%s\". OS errno is %d", pathname, errcode);
		if (!errorLogged)
		{
			errorLogged = true;
			gds__log(err.c_str());
		}
		Firebird::fatal_exception::raise(err.c_str());
	}

	if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
	{
		err.printf("Can't create directory \"%s\". File with same name already exists", pathname);
		if (!errorLogged)
		{
			errorLogged = true;
			gds__log(err.c_str());
		}
		Firebird::fatal_exception::raise(err.c_str());
	}

	if (attr & FILE_ATTRIBUTE_READONLY)
	{
		err.printf("Can't create directory \"%s\". Readonly directory with same name already exists", pathname);
		if (!errorLogged)
		{
			errorLogged = true;
			gds__log(err.c_str());
		}
		Firebird::fatal_exception::raise(err.c_str());
	}
}
Example #12
0
ISC_STATUS API_ROUTINE isc_delete_user(ISC_STATUS* status, const USER_SEC_DATA* input_user_data)
{
/**************************************
 *
 *      i s c _ d e l e t e _ u s e r
 *
 **************************************
 *
 * Functional description
 *      Deletes a user from the server's security
 *	    database.
 *      Return 0 if the user was deleted
 *
 *	    Return > 0 if any error occurs.
 *
 **************************************/
	Auth::StackUserData userInfo;
	userInfo.op = Auth::DEL_OPER;
	Firebird::LocalStatus s;
	Firebird::CheckStatusWrapper statusWrapper(&s);

	if (input_user_data->user_name)
	{
		Firebird::string work = input_user_data->user_name;
		if (work.length() > USERNAME_LENGTH) {
			return user_error(status, isc_usrname_too_long);
		}

		Firebird::string::size_type l = work.find(' ');
		if (l != Firebird::string::npos) {
			work.resize(l);
		}

		userInfo.user.set(&statusWrapper, work.c_str());
		Firebird::check(&statusWrapper);
		userInfo.user.setEntered(&statusWrapper, 1);
		Firebird::check(&statusWrapper);
	}
	else {
		return user_error(status, isc_usrname_required);
	}

	return executeSecurityCommand(status, input_user_data, userInfo);
}
Example #13
0
// static function
bool Switches::matchSwitch(const Firebird::string& sw, const char* target, size_t n)
{
/**************************************
 *
 *	m a t c h S w i t c h
 *
 **************************************
 *
 * Functional description
 *	Returns true if switch matches target
 *
 **************************************/
	if (n < sw.length())
	{
		return false;
	}
	n = sw.length();
	return memcmp(sw.c_str(), target, n) == 0;
}
Example #14
0
ModuleLoader::Module* ModuleLoader::loadModule(const Firebird::PathName& modPath)
{
	void* module = dlopen(modPath.nullStr(), FB_RTLD_MODE);
	if (module == NULL)
	{
#ifdef DEV_BUILD
//		gds__log("loadModule failed loading %s: %s", modPath.c_str(), dlerror());
#endif
		return 0;
	}

#ifdef DEBUG_THREAD_IN_UNLOADED_LIBRARY
	Firebird::string command;
	command.printf("echo +++ %s +++ >>/tmp/fbmaps;date >> /tmp/fbmaps;cat /proc/%d/maps >>/tmp/fbmaps",
		modPath.c_str(), getpid());
	system(command.c_str());
#endif

	return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(module);
}
Example #15
0
void* DlfcnModule::findSymbol(const Firebird::string& symName)
{
	void* result = dlsym(module, symName.c_str());
	if (!result)
	{
		Firebird::string newSym = '_' + symName;

		result = dlsym(module, newSym.c_str());
	}

#ifdef HAVE_DLADDR
	if (!PathUtils::isRelative(fileName))
	{
		Dl_info info;
		if (!dladdr(result, &info))
			return NULL;
		if (fileName != info.dli_fname)
			return NULL;
	}
#endif

	return result;
}
Example #16
0
int CLIB_ROUTINE main( int argc, char **argv)
{
/**************************************
 *
 *	m a i n
 *
 **************************************
 *
 * Functional description
 *	Install or remove a Firebird service.
 *
 **************************************/
	USHORT sw_command = COMMAND_NONE;
	bool sw_version = false;
	USHORT sw_startup = STARTUP_AUTO;
	USHORT sw_mode = DEFAULT_PRIORITY;
	USHORT sw_guardian = NO_GUARDIAN;
	USHORT sw_arch = ARCH_SS;
	bool sw_interactive = false;

	const TEXT* instance = FB_DEFAULT_INSTANCE;

	const TEXT* username = NULL;
	const TEXT* password = NULL;

	// Let's get the root directory from the instance path of this program.
	// argv[0] is only _mostly_ guaranteed to give this info,
	// so we GetModuleFileName()
	TEXT directory[MAXPATHLEN];
	const USHORT len = GetModuleFileName(NULL, directory, sizeof(directory));
	if (len == 0)
		return svc_error(GetLastError(), "GetModuleFileName", NULL);

	fb_assert(len <= sizeof(directory));

	// Get to the last '\' (this one precedes the filename part). There is
	// always one after a call to GetModuleFileName().
	TEXT* p = directory + len;

	while (p != directory)
	{
		--p;

		if ((*p) == '\\')
			break;
	}
	*p = '\0';

	TEXT full_username[128];
	TEXT oem_username[128];
	TEXT keyb_password[64];

	const TEXT* const* const end = argv + argc;
	while (++argv < end)
	{
		if (**argv != '-')
		{
			int i;
			const TEXT* cmd;
			for (i = 0; cmd = commands[i].name; i++)
			{
				const TEXT* q;
				for (p = *argv, q = cmd; *p && UPPER(*p) == *q; p++, q++)
					;
				if (!*p && commands[i].abbrev <= (USHORT) (q - cmd))
					break;
			}
			if (!cmd)
			{
				printf("Unknown command \"%s\"\n", *argv);
				usage_exit();
			}
			sw_command = commands[i].code;
		}
		else
		{
			p = *argv + 1;
			switch (UPPER(*p))
			{
				case 'A':
					sw_startup = STARTUP_AUTO;
					break;

				case 'D':
					sw_startup = STARTUP_DEMAND;
					break;

				/*
				case 'R':
					sw_mode = NORMAL_PRIORITY;
					break;
				*/
				case 'B':
					sw_mode = HIGH_PRIORITY;
					break;

				case 'Z':
					sw_version = true;
					break;

				case 'G':
					sw_guardian = USE_GUARDIAN;
					break;

				case 'L':
					if (++argv < end)
						username = *argv;
					if (++argv < end)
					{
						if (**argv == '-')	// Next switch
							--argv;
						else
							password = *argv;
					}
					break;

				case 'I':
					sw_interactive = true;
					break;

				case 'N':
					if (++argv < end)
						instance = *argv;
					break;

				case '?':
					usage_exit();

				default:
					printf("Unknown switch \"%s\"\n", p);
					usage_exit();
			}
		}
	}

	if (sw_version)
		printf("instsvc version %s\n", FB_VERSION);

	if (sw_command == COMMAND_NONE || (username && sw_command != COMMAND_INSTALL))
	{
		usage_exit();
	}

	if (sw_command == COMMAND_INSTALL && username != 0)
	{
		if (sw_interactive)
		{
			printf("\"Interact with desktop\" mode can be set for LocalSystem account only");
			exit(FINI_ERROR);
		}

		const char* limit = username;
		while (*limit != '\0' && *limit != '\\')
			++limit;

		if (!*limit)
		{
			DWORD cnlen = sizeof(full_username) - 1;
			GetComputerName(full_username, &cnlen);
			strcat(full_username, "\\");
			strncat(full_username, username, sizeof(full_username) - (cnlen + 1));
		}
		else
		{
			strncpy(full_username, username, sizeof(full_username));
		}

		full_username[sizeof(full_username) - 1] = '\0';

		CharToOem(full_username, oem_username);

		username = full_username;

		if (password == 0)
		{
			printf("Enter %s user password : "******"\n");
			OemToChar(keyb_password, keyb_password);
			password = keyb_password;
		}

		// Let's grant "Logon as a Service" right to the -login user
		switch (SERVICES_grant_privilege(full_username, svc_error, L"SeServiceLogonRight"))
		{
			case FB_PRIVILEGE_ALREADY_GRANTED:
				/*
				// OM - I think it is better not to bother the admin with this message.
				printf("The 'Logon as a Service' right was already granted to %s\n", oem_username);
				*/
				break;
			case FB_SUCCESS:
				printf("The 'Logon as a Service' right has been granted to %s\n", oem_username);
				break;
			case FB_FAILURE:
			default:
				printf("Failed granting the 'Logon as a Service' right to %s\n", oem_username);
				exit(FINI_ERROR);
				break;
		}

		// Let's grant "Adjust memory quotas for a process" right to the -login user
		switch (SERVICES_grant_privilege(full_username, svc_error, L"SeIncreaseQuotaPrivilege"))
		{
			case FB_PRIVILEGE_ALREADY_GRANTED:
				break;
			case FB_SUCCESS:
				printf("The 'Adjust memory quotas for a process' right has been granted to %s\n", oem_username);
				break;
			case FB_FAILURE:
			default:
				printf("Failed granting the 'Adjust memory quotas for a process' right to %s\n", oem_username);
				exit(FINI_ERROR);
				break;
		}
	}

	DWORD dwScmManagerAccess = SC_MANAGER_ALL_ACCESS;

	switch (sw_command)
	{
		case COMMAND_INSTALL:
		case COMMAND_REMOVE:
			dwScmManagerAccess = SC_MANAGER_CREATE_SERVICE;
			break;

		case COMMAND_START:
		case COMMAND_STOP:
			dwScmManagerAccess = SC_MANAGER_CONNECT;
			break;

		case COMMAND_QUERY:
			dwScmManagerAccess = SC_MANAGER_ENUMERATE_SERVICE;
			break;
    }

	const SC_HANDLE manager = OpenSCManager(NULL, NULL, dwScmManagerAccess);
	if (manager == NULL)
	{
		svc_error(GetLastError(), "OpenSCManager", NULL);
		exit(FINI_ERROR);
	}

	USHORT status, status2;
	SC_HANDLE service;

	Firebird::string guard_service_name, guard_display_name;
	guard_service_name.printf(ISCGUARD_SERVICE, instance);
	guard_display_name.printf(ISCGUARD_DISPLAY_NAME, instance);

	Firebird::string remote_service_name, remote_display_name;
	remote_service_name.printf(REMOTE_SERVICE, instance);
	remote_display_name.printf(REMOTE_DISPLAY_NAME, instance);

	Firebird::string switches;
	if (strchr(instance, ' '))
		switches.printf("-s \"%s\"", instance);
	else
		switches.printf("-s %s", instance);

	switch (sw_command)
	{
		case COMMAND_INSTALL:
			// First, lets do the guardian, if it has been specified
			if (sw_guardian)
			{
				status = SERVICES_install(manager,
										  guard_service_name.c_str(),
										  guard_display_name.c_str(),
										  ISCGUARD_DISPLAY_DESCR,
										  ISCGUARD_EXECUTABLE,
										  directory,
										  switches.c_str(),
										  NULL,
										  sw_startup,
										  username,
										  password,
										  false, // interactive_mode
										  true, // auto_restart
										  svc_error);

				status2 = FB_SUCCESS;

				if (username != 0)
				{
					status2 =
						SERVICES_grant_access_rights(guard_service_name.c_str(), username, svc_error);
				}

				if (status == FB_SUCCESS && status2 == FB_SUCCESS)
				{
					printf("Service \"%s\" successfully created.\n", guard_display_name.c_str());
				}

				// Set sw_startup to manual in preparation for install the service
				sw_startup = STARTUP_DEMAND;
			}

			// do the install of the server
			status = SERVICES_install(manager,
									  remote_service_name.c_str(),
									  remote_display_name.c_str(),
									  REMOTE_DISPLAY_DESCR,
									  REMOTE_EXECUTABLE,
									  directory,
									  switches.c_str(),
									  NULL,
									  sw_startup,
									  username,
									  password,
									  sw_interactive,
									  !sw_guardian,
									  svc_error);

			status2 = FB_SUCCESS;

			if (username != 0)
			{
				status2 =
					SERVICES_grant_access_rights(remote_service_name.c_str(), username, svc_error);
			}

			if (status == FB_SUCCESS && status2 == FB_SUCCESS)
			{
				printf("Service \"%s\" successfully created.\n", remote_display_name.c_str());
			}

			break;

		case COMMAND_REMOVE:
			service = OpenService(manager, guard_service_name.c_str(), SERVICE_ALL_ACCESS);
			if (service)
			{
				CloseServiceHandle(service);

				status = SERVICES_remove(manager, guard_service_name.c_str(),
										 /*guard_display_name.c_str(),*/ svc_error);

				if (status == FB_SUCCESS)
				{
					printf("Service \"%s\" successfully deleted.\n", guard_display_name.c_str());
				}
				else if (status == IB_SERVICE_RUNNING)
				{
					printf("Service \"%s\" not deleted.\n", guard_display_name.c_str());
					printf("You must stop it before attempting to delete it.\n\n");
				}
			}
			else
			{
				status = (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) ? FB_SUCCESS : FB_FAILURE;
			}

			service = OpenService(manager, remote_service_name.c_str(), SERVICE_ALL_ACCESS);
			if (service)
			{
				CloseServiceHandle(service);

				status2 = SERVICES_remove(manager, remote_service_name.c_str(),
										  /*remote_display_name.c_str(),*/ svc_error);

				if (status2 == FB_SUCCESS)
				{
					printf("Service \"%s\" successfully deleted.\n", remote_display_name.c_str());
				}
				else if (status2 == IB_SERVICE_RUNNING)
				{
					printf("Service \"%s\" not deleted.\n", remote_display_name.c_str());
					printf("You must stop it before attempting to delete it.\n\n");
				}
			}
			else
			{
				status2 = (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) ? FB_SUCCESS : FB_FAILURE;
			}

			if (status != FB_SUCCESS && status2 != FB_SUCCESS)
				status = FB_FAILURE;

			break;

		case COMMAND_START:
			// Test for use of the guardian. If so, start the guardian else start the server
			service = OpenService(manager, guard_service_name.c_str(), SERVICE_START);
			if (service)
			{
				CloseServiceHandle(service);

				status = SERVICES_start(manager, guard_service_name.c_str(),
										/*guard_display_name.c_str(),*/ sw_mode, svc_error);

				if (status == FB_SUCCESS)
				{
					printf("Service \"%s\" successfully started.\n", guard_display_name.c_str());
				}
			}
			else
			{
				CloseServiceHandle(service);

				status = SERVICES_start(manager, remote_service_name.c_str(),
										/*remote_display_name.c_str(),*/ sw_mode, svc_error);

				if (status == FB_SUCCESS)
				{
					printf("Service \"%s\" successfully started.\n", remote_display_name.c_str());
				}
			}
			break;

		case COMMAND_STOP:
			// Test for use of the guardian. If so, stop the guardian else stop the server
			service = OpenService(manager, guard_service_name.c_str(), SERVICE_STOP);
			if (service)
			{
				CloseServiceHandle(service);

				status = SERVICES_stop(manager, guard_service_name.c_str(),
									   /*guard_display_name.c_str(),*/ svc_error);

				if (status == FB_SUCCESS)
				{
					printf("Service \"%s\" successfully stopped.\n", guard_display_name.c_str());
				}
			}
			else
			{
				CloseServiceHandle(service);

				status = SERVICES_stop(manager, remote_service_name.c_str(),
									   /*remote_display_name.c_str(),*/ svc_error);

				if (status == FB_SUCCESS)
				{
					printf("Service \"%s\" successfully stopped.\n", remote_display_name.c_str());
				}
			}
			break;

		case COMMAND_QUERY:
			if (svc_query_ex(manager) == FB_FAILURE)
			{
				svc_query(guard_service_name.c_str(), guard_display_name.c_str(), manager);
				svc_query(remote_service_name.c_str(), remote_display_name.c_str(), manager);
			}

			status = FB_SUCCESS;
			break;

		default:
			status = FB_SUCCESS;
	}

	CloseServiceHandle(manager);

	return (status == FB_SUCCESS) ? FINI_OK : FINI_ERROR;
}
Example #17
0
int CLIB_ROUTINE main( int argc, char **argv)
{
    /**************************************
     *
     *	m a i n
     *
     **************************************
     *
     * Functional description
     *	If there is no command line, prompt for one, read it
     *	and make an artificial argc/argv.   Otherwise, pass
     *	the specified argc/argv to IBMGR_exec_line (see below).
     *
     **************************************/

    fprintf(stderr, "*** fbmgr is deprecated, will be removed soon ***\n");
    gds__log("*** fbmgr is deprecated, will be removed soon ***");

    // Let's see if we have something in environment variables
    Firebird::string user, password;
    fb_utils::readenv(ISC_USER, user);
    fb_utils::readenv(ISC_PASSWORD, password);

    Firebird::string host;
    // MMM - do not allow to change host now
    //fb_utils::readenv("ISC_HOST", host);

    TEXT msg[MSG_LEN];

    // Let's get a real user name. This info is used by
    // START server command. Because server is not running
    // we can not check the password, thus we require a
    // real user to be root or FIREBIRD_USER_NAME or
    // INTERBASE_USER_NAME or INTERBASE_USER_SHORT

    const struct passwd* pw = getpwuid(getuid());
    if (pw == NULL)
    {
        perror("getpwuid");
        SRVRMGR_msg_get(MSG_GETPWFAIL, msg);
        fprintf(OUTFILE, "%s\n", msg);
        exit(FINI_ERROR);
    }

    strcpy(ibmgr_data.real_user, pw->pw_name);

    if (!strcmp(pw->pw_name, "root") ||
            !strcmp(pw->pw_name, FIREBIRD_USER_NAME) ||
            !strcmp(pw->pw_name, INTERBASE_USER_NAME) ||
            !strcmp(pw->pw_name, INTERBASE_USER_SHORT))
    {
        strcpy(ibmgr_data.user, SYSDBA_USER_NAME);
    }
    else
        copy_str_upper(ibmgr_data.user, pw->pw_name);


    if (user.length())
        copy_str_upper(ibmgr_data.user, user.c_str());

    if (password.length())
        strcpy(ibmgr_data.password, password.c_str());
    else
        ibmgr_data.password[0] = '\0';

    if (host.length())
        strcpy(ibmgr_data.host, host.c_str());
    else
        strcpy(ibmgr_data.host, "localhost");


    // Shutdown is not in progress and we are not attached to service yet.
    // But obviously we will need attachment.

    ibmgr_data.shutdown = false;
    ibmgr_data.attached = 0;
    ibmgr_data.reattach |= (REA_HOST | REA_USER | REA_PASSWORD);

    // No pidfile by default
    ibmgr_data.pidfile[0] = 0;



    // Special case a solitary -z switch.
    // Print the version and then drop into prompt mode.

    if (argc == 2 && *argv[1] == '-' && (argv[1][1] == 'Z' || argv[1][1] == 'z'))
    {
        parse_cmd_line(argc, argv, false);
        argc--;
    }

    SSHORT ret;
    if (argc > 1)
    {
        ret = parse_cmd_line(argc, argv, true);
        if (ret == FB_SUCCESS)
        {
            ret = SRVRMGR_exec_line(&ibmgr_data);
            if (ret)
            {
                SRVRMGR_msg_get(ret, msg);
                fprintf(OUTFILE, "%s\n", msg);
            }
            // We also need to check the shutdown flag here (if operation was
            // -shut -[noat|notr]) and, depending on what we want to do, either
            // wait here on some sort of a shutdown event, or go to the prompt mode
            SRVRMGR_cleanup(&ibmgr_data);
            exit(FINI_OK);
        }
        else if (ret != ACT_PROMPT)
            exit(FINI_OK);
    }

    int local_argc;
    SCHAR* local_argv[MAXARGS];
    TEXT stuff[MAXSTUFF];

    for (;;)
    {
        if (get_line(&local_argc, local_argv, stuff))
            break;
        if (local_argc > 1)
        {
            ret = parse_cmd_line(local_argc, local_argv, false);
            if (ret == ACT_QUIT)
                break;
            if (ret == FB_SUCCESS)
            {
                ret = SRVRMGR_exec_line(&ibmgr_data);
                if (ret)
                {
                    SRVRMGR_msg_get(ret, msg);
                    fprintf(OUTFILE, "%s\n", msg);
                }
            }
        }
    }
    SRVRMGR_cleanup(&ibmgr_data);
    exit(FINI_OK);
}
Example #18
0
qli_tok* LEX_token()
{
/**************************************
 *
 *	L E X _ t o k e n
 *
 **************************************
 *
 * Functional description
 *	Parse and return the next token.
 *
 **************************************/
	qli_tok* token = QLI_token;
	TEXT* p = token->tok_string;

	// Get next significant byte.  If it's the last EOL of a blob, throw it away

	SSHORT c;

	for (;;)
	{
		c = skip_white();
		if (c != '\n' || QLI_line->line_type != line_blob)
			break;
		qli_line* prior = QLI_line;
		next_line(true);
		if (prior == QLI_line)
			break;
	}

	// If we hit end of file, make up a phoney token

	if (!QLI_line)
	{
		const TEXT* q = eof_string;
		while (*p++ = *q++);
		token->tok_type = tok_eof;
		token->tok_keyword = KW_none;
		return NULL;
	}

	*p++ = c;
	QLI_token->tok_position = QLI_line->line_position + QLI_line->line_ptr - QLI_line->line_data - 1;

	// On end of file, generate furious but phone end of line tokens

	char char_class = classes(c);

	if (char_class & CHR_letter)
	{
		for (c = nextchar(true); classes(c) & CHR_ident; c = nextchar(true))
			*p++ = c;
		retchar();
		token->tok_type = tok_ident;
	}
	else if (((char_class & CHR_digit) || c == '.') && scan_number(c, &p))
		token->tok_type = tok_number;
	else if (char_class & CHR_quote)
	{
		token->tok_type = tok_quoted;
		while (true)
		{
			const SSHORT next = nextchar(false);
			if (!next || next == '\n')
			{
				retchar();
				IBERROR(63);	// Msg 63 unterminated quoted string
				break;
			}
			*p++ = next;
			if ((p - token->tok_string) >= MAXSYMLEN)
				ERRQ_msg_put(470, SafeArg() << MAXSYMLEN);	// Msg 470 literal too long

			// If there are 2 quotes in a row, interpret 2nd as a literal

			if (next == c)
			{
				const SSHORT peek = nextchar(false);
				retchar();
				if (peek != c)
					break;
				nextchar(false);
			}
		}
	}
	else if (c == '\n')
	{
	    // end of line, signal it properly with a phoney token.
		token->tok_type = tok_eol;
		--p;
		const TEXT* q = eol_string;
		while (*q)
			*p++ = *q++;
	}
	else
	{
		token->tok_type = tok_punct;
		*p++ = nextchar(true);
		if (!HSH_lookup(token->tok_string, 2))
		{
			retchar();
			--p;
		}
	}

	token->tok_length = p - token->tok_string;
	*p = '\0';

	if (token->tok_string[0] == '$' && trans_limit < TRANS_LIMIT)
	{
		Firebird::string s;
		if (fb_utils::readenv(token->tok_string + 1, s))
		{
			LEX_push_string(s.c_str());
			++trans_limit;
			token = LEX_token();
			--trans_limit;
			return token;
		}
	}

    qli_symbol* symbol = HSH_lookup(token->tok_string, token->tok_length);
	token->tok_symbol = symbol;
	if (symbol && symbol->sym_type == SYM_keyword)
		token->tok_keyword = (kwwords) symbol->sym_keyword;
	else
		token->tok_keyword = KW_none;

	if (sw_trace)
		puts(token->tok_string);

	return token;
}
Example #19
0
/**

	callRemoteServiceManager

	@brief	Calls service manager to execute command,
	specified in userInfo


	@param status
	@param handle
	@param userInfo
	@param outputFunction
	@param functionArg

 **/
void callRemoteServiceManager(ISC_STATUS* status,
							  isc_svc_handle handle,
							  Auth::UserData& userData,
							  Firebird::IListUsers* callback)
{
	char spb_buffer[1024];
	char* spb = spb_buffer;
	const int op = userData.op;
	if (op != Auth::DIS_OPER &&
		op != Auth::OLD_DIS_OPER &&
		op != Auth::MAP_SET_OPER &&
		op != Auth::MAP_DROP_OPER &&
		!userData.user.entered())
	{
	    status[0] = isc_arg_gds;
	    status[1] = isc_gsec_switches_error;
	    status[2] = isc_arg_end;
		return;
	}

	switch (op)
	{
	case Auth::ADD_OPER:
		stuffSpbByte(spb, isc_action_svc_add_user);
		userInfoToSpb(spb, userData);
		break;

	case Auth::MOD_OPER:
		stuffSpbByte(spb, isc_action_svc_modify_user);
		userInfoToSpb(spb, userData);
		break;

	case Auth::DEL_OPER:
		stuffSpbByte(spb, isc_action_svc_delete_user);
		stuffSpb2(spb, isc_spb_sec_username, userData.user.get());
		if (userData.role.entered())
		{
			stuffSpb2(spb, isc_spb_sql_role_name, userData.role.get());
		}
		break;

	case Auth::DIS_OPER:
	case Auth::OLD_DIS_OPER:
		{
			char usersDisplayTag = 0;
			checkServerUsersVersion(handle, usersDisplayTag);
			stuffSpbByte(spb, usersDisplayTag);
		}
		if (userData.user.entered())
		{
			stuffSpb2(spb, isc_spb_sec_username, userData.user.get());
		}
		if (userData.role.entered())
		{
			stuffSpb2(spb, isc_spb_sql_role_name, userData.role.get());
		}
		break;

	case Auth::MAP_SET_OPER:
		stuffSpbByte(spb, isc_action_svc_set_mapping);
		break;

	case Auth::MAP_DROP_OPER:
		stuffSpbByte(spb, isc_action_svc_drop_mapping);
		break;

	default:
	    status[0] = isc_arg_gds;
	    status[1] = isc_gsec_switches_error;
	    status[2] = isc_arg_end;
		return;
	}

	if (userData.database.entered()) {
		stuffSpb2(spb, isc_spb_dbname, userData.database.get());
	}

	fb_assert((size_t)(spb - spb_buffer) <= sizeof(spb_buffer));
	if (isc_service_start(status, &handle, 0, static_cast<USHORT>(spb - spb_buffer), spb_buffer) != 0)
	{
		return;
	}

	spb = spb_buffer;
	stuffSpbByte(spb, isc_info_svc_timeout);
	stuffSpbShort(spb, 4);
	stuffSpbLong(spb, 10);

	char resultBuffer[RESULT_BUF_SIZE + 4];
	Firebird::string text;

	ISC_STATUS_ARRAY temp_status;
	ISC_STATUS* local_status = status[1] ? temp_status : status;
	fb_utils::init_status(local_status);

	if (op == Auth::DIS_OPER || op == Auth::OLD_DIS_OPER)
	{
		const char request[] = {isc_info_svc_get_users};
		int startQuery = 0;
		Auth::StackUserData uData;

		for (;;)
		{
			isc_resv_handle reserved = 0;
			isc_service_query(local_status, &handle, &reserved, static_cast<USHORT>(spb - spb_buffer), spb_buffer,
				sizeof(request), request, RESULT_BUF_SIZE - startQuery, &resultBuffer[startQuery]);
			if (local_status[1])
			{
				return;
			}
			startQuery = typeBuffer(local_status, resultBuffer, startQuery, uData, callback, text);
			if (startQuery < 0)
			{
				break;
			}
		}

		if (uData.user.get()[0] && callback)
		{
			LocalStatus status;
			CheckStatusWrapper statusWrapper(&status);

			setAttr(&statusWrapper, &uData);
			check(&statusWrapper);
			callback->list(&statusWrapper, &uData);
			check(&statusWrapper);
		}
	}
	else
	{
		const char request = isc_info_svc_line;
		for (;;)
		{
			isc_resv_handle reserved = 0;
			isc_service_query(local_status, &handle, &reserved, 0, NULL,
				1, &request, RESULT_BUF_SIZE, resultBuffer);
			if (local_status[1])
			{
				return;
			}
			char *p = resultBuffer;
			if (*p++ == isc_info_svc_line)
			{
				FB_SIZE_T len = static_cast<FB_SIZE_T>(isc_vax_integer(p, sizeof(USHORT)));
				p += sizeof(USHORT);
				if (len > RESULT_BUF_SIZE)
				{
					len = RESULT_BUF_SIZE;
				}
				if (!len)
				{
					if (*p == isc_info_data_not_ready)
						continue;
					if (*p == isc_info_end)
						break;
				}
				p[len] = 0;
				text += p;
			}
		}

	}

	if (! text.isEmpty())
	{
		local_status[0] = isc_arg_interpreted;
		// strdup - memory leak in case of errors
		local_status[1] = reinterpret_cast<ISC_STATUS>(strdup(text.c_str()));
		local_status[2] = isc_arg_end;
	}
}
Example #20
0
// allow different users to read\write\delete files in lock directory
// in case of any error just log it and don't stop engine execution
void adjustLockDirectoryAccess(const char* pathname)
{
	PSECURITY_DESCRIPTOR pSecDesc = NULL;
	PSID pSID_Users = NULL;
	PSID pSID_Administrators = NULL;
	PACL pNewACL = NULL;
	try
	{
		// We should pass root directory in format "C:\" into GetVolumeInformation().
		// In case of pathname is not local folder (i.e. \\share\folder) let
		// GetVolumeInformation() return an error.
		Firebird::PathName root(pathname);
		const Firebird::PathName::size_type pos = root.find(':', 0);
		if (pos == 1)
		{
			root.erase(pos + 1, root.length());
			PathUtils::ensureSeparator(root);
		}

		DWORD fsflags;
		if (!GetVolumeInformation(root.c_str(), NULL, 0, NULL, NULL, &fsflags, NULL, 0))
			Firebird::system_error::raise("GetVolumeInformation");

		if (!(fsflags & FS_PERSISTENT_ACLS))
			return;

		// Adjust security for our new folder : allow BUILTIN\Users group to
		// read\write\delete files
		PACL pOldACL = NULL;

		if (GetNamedSecurityInfo((LPSTR) pathname,
				SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
				NULL, NULL, &pOldACL, NULL,
				&pSecDesc) != ERROR_SUCCESS)
		{
			Firebird::system_error::raise("GetNamedSecurityInfo");
		}

		SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
		if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pSID_Users))
		{
			Firebird::system_error::raise("AllocateAndInitializeSid");
		}

		if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID_Administrators))
		{
			Firebird::system_error::raise("AllocateAndInitializeSid");
		}

		EXPLICIT_ACCESS eas[2];
		memset(eas, 0, sizeof(eas));

		eas[0].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
		eas[0].grfAccessMode = GRANT_ACCESS;
		eas[0].grfInheritance = SUB_OBJECTS_ONLY_INHERIT;
		eas[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
		eas[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
		eas[0].Trustee.ptstrName  = (LPSTR) pSID_Users;

		eas[1].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
		eas[1].grfAccessMode = GRANT_ACCESS;
		eas[1].grfInheritance = SUB_OBJECTS_ONLY_INHERIT;
		eas[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
		eas[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
		eas[1].Trustee.ptstrName  = (LPSTR) pSID_Administrators;

		if (SetEntriesInAcl(2, eas, pOldACL, &pNewACL) != ERROR_SUCCESS)
			Firebird::system_error::raise("SetEntriesInAcl");

		if (SetNamedSecurityInfo((LPSTR) pathname,
				SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
				NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS)
		{
			Firebird::system_error::raise("SetNamedSecurityInfo");
		}
	}
	catch (const Firebird::Exception& ex)
	{
		Firebird::string str;
		str.printf("Error adjusting access rights for folder \"%s\" :", pathname);

		iscLogException(str.c_str(), ex);
	}

	if (pSID_Users) {
		FreeSid(pSID_Users);
	}
	if (pSID_Administrators) {
		FreeSid(pSID_Administrators);
	}
	if (pNewACL) {
		LocalFree(pNewACL);
	}
	if (pSecDesc) {
		LocalFree(pSecDesc);
	}
}
Example #21
0
	void CryptoManager::changeCryptState(thread_db* tdbb, const Firebird::string& plugName)
	{
		if (plugName.length() > 31)
		{
			(Arg::Gds(isc_cp_name_too_long) << Arg::Num(31)).raise();
		}

		bool newCryptState = plugName.hasData();

		{	// window scope
			Header hdr(tdbb, LCK_write);

			// Check header page for flags
			if (hdr->hdr_flags & Ods::hdr_crypt_process)
			{
				(Arg::Gds(isc_cp_process_active)).raise();
			}

			bool headerCryptState = hdr->hdr_flags & Ods::hdr_encrypted;
			if (headerCryptState == newCryptState)
			{
				(Arg::Gds(isc_cp_already_crypted)).raise();
			}

			fb_assert(stateLock);
			// Take exclusive stateLock
			bool ret = needLock ? LCK_lock(tdbb, stateLock, LCK_PW, LCK_WAIT) :
								  LCK_convert(tdbb, stateLock, LCK_PW, LCK_WAIT);
			if (!ret)
			{
				fb_assert(tdbb->tdbb_status_vector[1]);
				ERR_punt();
			}
			fb_utils::init_status(tdbb->tdbb_status_vector);
			needLock = false;

			// Load plugin
			if (newCryptState)
			{
				loadPlugin(plugName.c_str());
			}
			crypt = newCryptState;

			// Write modified header page
			Ods::header_page* header = hdr.write();
			if (crypt)
			{
				header->hdr_flags |= Ods::hdr_encrypted;
				plugName.copyTo(header->hdr_crypt_plugin, sizeof header->hdr_crypt_plugin);
			}
			else
			{
				header->hdr_flags &= ~Ods::hdr_encrypted;
			}
			header->hdr_flags |= Ods::hdr_crypt_process;
			process = true;
		}

		// Trigger lock on ChangeCryptState
		if (!LCK_convert(tdbb, stateLock, LCK_EX, LCK_WAIT))
		{
			ERR_punt();
		}

		if (!LCK_convert(tdbb, stateLock, LCK_SR, LCK_WAIT))
		{
			ERR_punt();
		}
		fb_utils::init_status(tdbb->tdbb_status_vector);

		// Now we may set hdr_crypt_page for crypt thread
		{	// window scope
			Header hdr(tdbb, LCK_write);
			Ods::header_page* header = hdr.write();
			header->hdr_crypt_page = 1;
		}

		startCryptThread(tdbb);
	}
Example #22
0
ISC_STATUS API_ROUTINE isc_modify_user(ISC_STATUS* status, const USER_SEC_DATA* input_user_data)
{
/**************************************
 *
 *      i s c _ m o d i f y _ u s e r
 *
 **************************************
 *
 * Functional description
 *      Adds a user to the server's security
 *	database.
 *      Return 0 if the user was added
 *
 *	    Return > 0 if any error occurs.
 *
 **************************************/
	Auth::StackUserData userInfo;
	userInfo.op = Auth::MOD_OPER;
	Firebird::LocalStatus s;
	Firebird::CheckStatusWrapper statusWrapper(&s);

	if (input_user_data->user_name)
	{
		Firebird::string work = input_user_data->user_name;
		if (work.length() > USERNAME_LENGTH) {
			return user_error(status, isc_usrname_too_long);
		}

		Firebird::string::size_type l = work.find(' ');
		if (l != Firebird::string::npos) {
			work.resize(l);
		}

		userInfo.user.set(&statusWrapper, work.c_str());
		check(&statusWrapper);
		userInfo.user.setEntered(&statusWrapper, 1);
		check(&statusWrapper);
	}
	else {
		return user_error(status, isc_usrname_required);
	}

	if (input_user_data->password)
	{
		userInfo.pass.set(&statusWrapper, input_user_data->password);
		check(&statusWrapper);
		userInfo.pass.setEntered(&statusWrapper, 1);
		check(&statusWrapper);
	}
	else {
		return user_error(status, isc_password_required);
	}

	copyField(userInfo.u, input_user_data->uid, input_user_data->sec_flags & sec_uid_spec);
	copyField(userInfo.g, input_user_data->gid, input_user_data->sec_flags & sec_gid_spec);
	copyField(userInfo.group, input_user_data->group_name, input_user_data->sec_flags & sec_group_name_spec);
	copyField(userInfo.first, input_user_data->first_name, input_user_data->sec_flags & sec_first_name_spec);
	copyField(userInfo.middle, input_user_data->middle_name, input_user_data->sec_flags & sec_middle_name_spec);
	copyField(userInfo.last, input_user_data->last_name, input_user_data->sec_flags & sec_last_name_spec);

	return executeSecurityCommand(status, input_user_data, userInfo);
}
Example #23
0
SINT64 ConfigFile::Parameter::asInteger() const
{
	if (value.isEmpty())
		return 0;

	SINT64 ret = 0;
	int sign = 1;
	int state = 1; // 1 - sign, 2 - numbers, 3 - multiplier

	Firebird::string trimmed = value;
	trimmed.trim(" \t");

	if (trimmed.isEmpty())
		return 0;

	const char* ch = trimmed.c_str();
	for (; *ch; ch++)
		switch (*ch)
		{
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			if (state > 2)
				return 0;
			state = 2;

			ret = ret * 10 + (*ch - '0');
			break;

		case '-':
			if (state > 1)
				return 0;

			sign = -sign;
			break;

		case ' ': case '\t':
			if (state == 1)
				break;
			return 0;

		case 'k': case 'K':
			if (state != 2)
				return 0;
			state = 3;

			ret = ret * 1024;
			break;

		case 'm': case 'M':
			if (state != 2)
				return 0;
			state = 3;

			ret = ret * 1024 * 1024;
			break;

		case 'g': case 'G':
			if (state != 2)
				return 0;
			state = 3;

			ret = ret * 1024 * 1024 * 1024;
			break;

		default:
			return 0;
		};

	return sign * ret;
}
Example #24
0
int gsec(Firebird::UtilSvc* uSvc)
{
/**************************************
 *
 *	c o m m o n _ m a i n
 *
 **************************************
 *
 * Functional description
 *	If there is no command line, prompt for one, read it
 *	and make an artificial argv.   Otherwise, pass
 *	the specified argv to SECURITY_exec_line (see below).
 *
 **************************************/
	int exit_code = FINI_OK;
	Firebird::UtilSvc::ArgvType& argv = uSvc->argv;

	TEXT stuff[MAXSTUFF];		// a place to put stuff in interactive mode

	tsec tsecInstance(uSvc);
	tsec* tdsec = &tsecInstance;
	tsec::putSpecific(tdsec);

	StackUserData u;
	tdsec->tsec_user_data = &u;

	const unsigned char* block;
	unsigned int bs = uSvc->getAuthBlock(&block);
	if (bs)
	{
		u.authenticationBlock.add(block, bs);
	}

	try {
	// Perform some special handling when run as a Firebird service.

	tdsec->tsec_throw = true;
	tdsec->tsec_interactive = !uSvc->isService();
	UserData* user_data = tdsec->tsec_user_data;

	//if (!uSvc->isService() && argv.getCount() == 1)
	//	GSEC_error(GsecMsg101); // use gsec -? to get help

	int ret = parse_cmd_line(argv, tdsec);
	if (!uSvc->isService() && ret == -2) // user asked for help
		GSEC_exit();

	Firebird::PathName databaseName;
	const bool databaseNameEntered = user_data->database.entered();
	if (databaseNameEntered)
	{
		databaseName = user_data->database.get();
	}
	else
	{
		const Firebird::RefPtr<Config> defConf(Config::getDefaultConfig());
		databaseName = defConf->getSecurityDatabase();
	}

	const Firebird::string sqlRoleName(user_data->role.entered() ? user_data->role.get() : "");

	Firebird::PathName serverName;
	const bool useServices = !uSvc->isService();

	switch (ISC_extract_host(databaseName, serverName, true))
	{
	case ISC_PROTOCOL_TCPIP:
		serverName += ":";
		break;
	case ISC_PROTOCOL_WLAN:
		serverName = "\\\\" + serverName + "\\";
		break;
	}

	if (!useServices)
	{
		serverName = "";
	}
	Firebird::LocalStatus s;
	user_data->database.set(&s, databaseName.c_str());
	check(&s);

	Firebird::RefPtr<IManagement> manager;
	ISC_STATUS_ARRAY status;

	if (!useServices)
	{
		// Get remote address info for management plugin
		Firebird::string network_protocol, remote_address;
		Firebird::ClumpletWriter tmp(Firebird::ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1);
		uSvc->fillDpb(tmp);

		if (tmp.find(isc_dpb_address_path))
		{
			Firebird::ClumpletReader address_stack(Firebird::ClumpletReader::UnTagged,
												   tmp.getBytes(), tmp.getClumpLength());

			while (!address_stack.isEof())
			{
				if (address_stack.getClumpTag() != isc_dpb_address)
				{
					address_stack.moveNext();
					continue;
				}

				Firebird::ClumpletReader address(Firebird::ClumpletReader::UnTagged,
												 address_stack.getBytes(), address_stack.getClumpLength());

				while (!address.isEof())
				{
					switch (address.getClumpTag())
					{
						case isc_dpb_addr_protocol:
							address.getString(network_protocol);
							break;
						case isc_dpb_addr_endpoint:
							address.getString(remote_address);
							break;
						default:
							break;
					}

					address.moveNext();
				}

				break;
			}
		}

		// Create config to pass -DATABASE parameter value to plugin
		Firebird::string databaseText;
		databaseText.printf("SecurityDatabase = %s\n", databaseName.c_str());
		ConfigFile gsecDatabase(ConfigFile::USE_TEXT, databaseText.c_str());
		Firebird::RefPtr<Config> defaultConfig(Config::getDefaultConfig());
		Firebird::RefPtr<Config> pseudoConfig(new Config(gsecDatabase, *defaultConfig));

		uSvc->checkService();

		fb_assert(user_data->dba.entered() || user_data->authenticationBlock.hasData());
		if (user_data->dba.entered() || user_data->authenticationBlock.hasData())
		{
			class GsecInfo : public Firebird::AutoIface<ILogonInfo, FB_AUTH_LOGON_INFO_VERSION>
			{
			public:
				GsecInfo(const char* pDba, const char* pRole,
						 const char* pProtocol, const char* pAddress,
						 const UserData::AuthenticationBlock* pAuthBlock)
					: dba(pDba), sqlRole(pRole),
					  protocol(pProtocol), address(pAddress),
					  authBytes(pAuthBlock->getCount() ? pAuthBlock->begin() : NULL),
					  authLength(pAuthBlock->getCount())
				{ }

				// ILogonInfo implementation
				const char* FB_CARG name()
				{
					return dba;
				}

				const char* FB_CARG role()
				{
					return sqlRole;
				}

				const char* FB_CARG networkProtocol()
				{
					return protocol;
				}

				const char* FB_CARG remoteAddress()
				{
					return address;
				}

				const unsigned char* FB_CARG authBlock(unsigned* length)
				{
					*length = authLength;
					return authBytes;
				}

			private:
				const char* dba;
				const char* sqlRole;
				const char* protocol;
				const char* address;
				const unsigned char* authBytes;
				unsigned int authLength;
			};
Example #25
0
void EVL_validate(thread_db* tdbb, const Item& item, const ItemInfo* itemInfo, dsc* desc, bool null)
{
/**************************************
 *
 *	E V L _ v a l i d a t e
 *
 **************************************
 *
 * Functional description
 *	Validate argument/variable for not null and check constraint
 *
 **************************************/
	if (itemInfo == NULL)
		return;

	jrd_req* request = tdbb->getRequest();
	bool err = false;

	if (null && !itemInfo->nullable)
		err = true;

	const char* value = NULL_STRING_MARK;
	VaryStr<128> temp;

	MapFieldInfo::ValueType fieldInfo;
	if (!err && itemInfo->fullDomain &&
		request->getStatement()->mapFieldInfo.get(itemInfo->field, fieldInfo) &&
		fieldInfo.validationExpr)
	{
		if (desc && null)
			desc->dsc_flags |= DSC_null;

		const bool desc_is_null = !desc || (desc->dsc_flags & DSC_null);

		request->req_domain_validation = desc;
		const USHORT flags = request->req_flags;

		if (!fieldInfo.validationExpr->execute(tdbb, request) && !(request->req_flags & req_null))
		{
			const USHORT length = desc_is_null ? 0 :
				MOV_make_string(desc, ttype_dynamic, &value, &temp, sizeof(temp) - 1);

			if (desc_is_null)
				value = NULL_STRING_MARK;
			else if (!length)
				value = "";
			else
				const_cast<char*>(value)[length] = 0;	// safe cast - data is on our local stack

			err = true;
		}

		request->req_flags = flags;
	}

	Firebird::string s;

	if (err)
	{
		ISC_STATUS status = isc_not_valid_for_var;
		const char* arg;

		if (item.type == Item::TYPE_CAST)
		{
			status = isc_not_valid_for;
			arg = "CAST";
		}
		else
		{
			if (itemInfo->name.isEmpty())
			{
				int index = item.index + 1;

				status = isc_not_valid_for;

				if (item.type == Item::TYPE_VARIABLE)
				{
					const jrd_prc* procedure = request->getStatement()->procedure;

					if (procedure)
					{
						if (index <= int(procedure->getOutputFields().getCount()))
							s.printf("output parameter number %d", index);
						else
						{
							s.printf("variable number %d",
								index - int(procedure->getOutputFields().getCount()));
						}
					}
					else
						s.printf("variable number %d", index);
				}
				else if (item.type == Item::TYPE_PARAMETER && item.subType == 0)
					s.printf("input parameter number %d", (index - 1) / 2 + 1);
				else if (item.type == Item::TYPE_PARAMETER && item.subType == 1)
					s.printf("output parameter number %d", index);

				if (s.isEmpty())
					arg = UNKNOWN_STRING_MARK;
				else
					arg = s.c_str();
			}
			else
				arg = itemInfo->name.c_str();
		}

		ERR_post(Arg::Gds(status) << Arg::Str(arg) << Arg::Str(value));
	}
}