diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx index 77f4c0ad1306..8c45a9a08350 100644 --- a/connectivity/source/drivers/firebird/Connection.cxx +++ b/connectivity/source/drivers/firebird/Connection.cxx @@ -121,7 +121,8 @@ struct ConnectionGuard } -void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info) +void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info, + const OUString& rDatabaseDataDirectoryURL) { ConnectionGuard aGuard(m_refCount); @@ -158,7 +159,7 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& bIsNewDatabase = !m_xEmbeddedStorage->hasElements(); - m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(nullptr, true)); + m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(&rDatabaseDataDirectoryURL, true)); m_pDatabaseFileDir->EnableKillingFile(); m_sFirebirdURL = m_pDatabaseFileDir->GetFileName() + "/firebird.fdb"; m_sFBKPath = m_pDatabaseFileDir->GetFileName() + "/firebird.fbk"; diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx index 524c0a7c476f..6ec020374883 100644 --- a/connectivity/source/drivers/firebird/Connection.hxx +++ b/connectivity/source/drivers/firebird/Connection.hxx @@ -165,7 +165,8 @@ namespace connectivity::firebird /// @throws css::sdbc::SQLException /// @throws css::uno::RuntimeException void construct( const OUString& url, - const css::uno::Sequence< css::beans::PropertyValue >& info); + const css::uno::Sequence< css::beans::PropertyValue >& info, + const OUString& rDatabaseDataDirectoryURL); const OUString& getConnectionURL() const {return m_sConnectionURL;} bool isEmbedded() const {return m_bIsEmbedded;} diff --git a/connectivity/source/drivers/firebird/Driver.cxx b/connectivity/source/drivers/firebird/Driver.cxx index 0879a7eca310..8292a3e7c14b 100644 --- a/connectivity/source/drivers/firebird/Driver.cxx +++ b/connectivity/source/drivers/firebird/Driver.cxx @@ -48,6 +48,7 @@ namespace { constexpr OUString our_sFirebirdTmpVar = u"FIREBIRD_TMP"_ustr; constexpr OUString our_sFirebirdLockVar = u"FIREBIRD_LOCK"_ustr; constexpr OUString our_sFirebirdMsgVar = u"FIREBIRD_MSG"_ustr; +constexpr OUString our_sFirebirdRootVar = u"FIREBIRD"_ustr; #ifdef MACOSX constexpr OUString our_sFirebirdLibVar = u"LIBREOFFICE_FIREBIRD_LIB"_ustr; #endif @@ -58,12 +59,15 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo , m_aContext(_rxContext) , m_firebirdTMPDirectory(nullptr, true) , m_firebirdLockDirectory(nullptr, true) + , m_firebirdDataDirectory(nullptr, true) + , m_bConfined(false) { // ::utl::TempFile uses a unique temporary directory (subdirectory of // /tmp or other user specific tmp directory) per instance in which // we can create directories for firebird at will. m_firebirdTMPDirectory.EnableKillingFile(true); m_firebirdLockDirectory.EnableKillingFile(true); + m_firebirdDataDirectory.EnableKillingFile(true); // Overrides firebird's default of /tmp or c:\temp osl_setEnvironment(our_sFirebirdTmpVar.pData, m_firebirdTMPDirectory.GetFileName().pData); @@ -71,6 +75,35 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo // Overrides firebird's default of /tmp/firebird or c:\temp\firebird osl_setEnvironment(our_sFirebirdLockVar.pData, m_firebirdLockDirectory.GetFileName().pData); + // Keep the files firebird opens or creates together in one directory. + // Embedded databases are extracted here, and DatabaseAccess = Restrict + // keeps any associated files firebird makes for it under the same + // directory. firebird reads this firebird.conf from the directory the + // FIREBIRD variable names, once, on its first use, so it has to be set + // before the first connection. + OUString sDataDirPath; + ::osl::FileBase::getSystemPathFromFileURL(m_firebirdDataDirectory.GetURL(), sDataDirPath); + + OString sConf = "DatabaseAccess = Restrict " + + OUStringToOString(sDataDirPath, RTL_TEXTENCODING_UTF8) + "\n"; + + OUString sConfURL = m_firebirdDataDirectory.GetURL() + "/firebird.conf"; + ::osl::File aConfFile(sConfURL); + if (aConfFile.open(osl_File_OpenFlag_Create | osl_File_OpenFlag_Write) == ::osl::FileBase::E_None) + { + sal_uInt64 nWritten = 0; + if (aConfFile.write(sConf.getStr(), sConf.getLength(), nWritten) == ::osl::FileBase::E_None + && nWritten == static_cast(sConf.getLength())) + { + osl_setEnvironment(our_sFirebirdRootVar.pData, sDataDirPath.pData); + m_bConfined = true; + } + aConfFile.close(); + } + + SAL_WARN_IF(!m_bConfined, "connectivity.firebird", + "could not write " << sConfURL << ", firebird connections will be refused"); + #ifndef SYSTEM_FIREBIRD // Overrides firebird's hardcoded default of /usr/local/firebird on *nix, // however on Windows it seems to use the current directory as a default. @@ -107,6 +140,7 @@ void FirebirdDriver::disposing() osl_clearEnvironment(our_sFirebirdTmpVar.pData); osl_clearEnvironment(our_sFirebirdLockVar.pData); + osl_clearEnvironment(our_sFirebirdRootVar.pData); #ifndef SYSTEM_FIREBIRD osl_clearEnvironment(our_sFirebirdMsgVar.pData); @@ -148,8 +182,18 @@ Reference< XConnection > SAL_CALL FirebirdDriver::connect( if ( ! acceptsURL(url) ) return nullptr; + // Without the firebird.conf that keeps firebird inside its own directory + // we do not open any database. + if (!m_bConfined) + { + ::connectivity::SharedResources aResources; + const OUString sMessage = aResources.getResourceString(STR_COULD_NOT_LOAD_FILE).replaceFirst( + "$filename$", u"firebird.conf"); + ::dbtools::throwGenericSQLException(sMessage, *this); + } + rtl::Reference pCon = new Connection(); - pCon->construct(url, info); + pCon->construct(url, info, getDatabaseDataDirectoryURL()); m_xConnections.push_back(pCon); diff --git a/connectivity/source/drivers/firebird/Driver.hxx b/connectivity/source/drivers/firebird/Driver.hxx index 5428568b4166..122fa1fc5f3d 100644 --- a/connectivity/source/drivers/firebird/Driver.hxx +++ b/connectivity/source/drivers/firebird/Driver.hxx @@ -48,6 +48,8 @@ namespace connectivity::firebird css::uno::Reference m_aContext; ::utl::TempFileNamed m_firebirdTMPDirectory; ::utl::TempFileNamed m_firebirdLockDirectory; + ::utl::TempFileNamed m_firebirdDataDirectory; + bool m_bConfined; protected: ::osl::Mutex m_aMutex; // mutex is need to control member access @@ -62,6 +64,11 @@ namespace connectivity::firebird virtual ~FirebirdDriver() override; const css::uno::Reference& getContext() const { return m_aContext; } + // The directory that embedded databases are extracted into. Each + // connection makes its own subdirectory here, and firebird keeps + // associated files it creates for them under this directory as well. + OUString getDatabaseDataDirectoryURL() const { return m_firebirdDataDirectory.GetURL(); } + // OComponentHelper virtual void SAL_CALL disposing() override;