From d24cd9cbd7d777a7929ef333f15c55e676ec10a6 Mon Sep 17 00:00:00 2001 From: alexpeshkoff Date: Fri, 23 Jul 2010 12:04:18 +0000 Subject: [PATCH] Implemented self-registering plugins format (same plugin can be easily linked statically or as dynamic library, depending upon platform requirements). Self-registering plugins need not export any functions, instead they call fb_register_plugin() on startup. Reworked all user management to use self-registering plugins. Removed system table RDB$USERS. PLG$USERS is not created automatically by plugin, but will be later (work in progress). --- builds/posix/Makefile.in.client.gsec | 3 +- builds/posix/Makefile.in.embed.util | 2 +- builds/posix/Makefile.in.fbserver | 9 +- builds/posix/Makefile.in.firebird | 9 +- builds/posix/Makefile.in.smp_server | 4 +- builds/posix/Makefile.in.user.management | 81 ++++++ builds/posix/firebird.vers | 5 + builds/posix/make.defaults | 4 + builds/posix/make.rules | 2 +- builds/posix/make.shared.variables | 8 +- configure.in | 1 + src/auth/Auth.cpp | 140 +---------- src/auth/Auth.h | 6 +- src/auth/AuthDbg.cpp | 133 ++++++++++ src/auth/AuthDbg.h | 95 +++++++ src/auth/AuthInterface.h | 32 +-- src/auth/SecurityDatabase/LegacyClient.cpp | 19 +- src/auth/SecurityDatabase/LegacyClient.h | 2 - .../SecurityDatabase/LegacyManagement.epp} | 238 ++++++++---------- src/auth/SecurityDatabase/LegacyManagement.h | 47 ++++ src/common/classes/ImplementHelper.h | 107 ++++++++ src/common/classes/Interface.h | 52 ++-- src/dbs/security.sql | 25 +- src/include/FirebirdPluginApi.h | 4 +- src/include/gen/ids.h | 16 +- src/jrd/PluginManager.h | 2 +- src/jrd/fields.h | 3 +- src/jrd/gds.cpp | 51 +++- src/jrd/idx.h | 4 - src/jrd/ini.epp | 29 --- src/jrd/jrd_pwd.h | 2 - src/jrd/names.h | 19 +- src/jrd/os/posix/mod_loader.cpp | 5 + src/jrd/pwd.cpp | 32 +-- src/jrd/relations.h | 16 +- src/misc/smallog.cpp | 121 +++++++++ src/plugins/udr_engine/UdrEngine.cpp | 2 +- src/remote/interface.cpp | 35 +-- src/remote/server.cpp | 25 +- src/utilities/gsec/security.cpp | 117 +++++++++ 40 files changed, 1021 insertions(+), 486 deletions(-) create mode 100644 builds/posix/Makefile.in.user.management create mode 100644 src/auth/AuthDbg.cpp create mode 100644 src/auth/AuthDbg.h rename src/{utilities/gsec/security.epp => auth/SecurityDatabase/LegacyManagement.epp} (67%) create mode 100644 src/auth/SecurityDatabase/LegacyManagement.h create mode 100644 src/common/classes/ImplementHelper.h create mode 100644 src/misc/smallog.cpp create mode 100644 src/utilities/gsec/security.cpp diff --git a/builds/posix/Makefile.in.client.gsec b/builds/posix/Makefile.in.client.gsec index 3bf7a88ab7..33c957e5ed 100644 --- a/builds/posix/Makefile.in.client.gsec +++ b/builds/posix/Makefile.in.client.gsec @@ -29,8 +29,7 @@ include $(ROOT)/gen/make.shared.variables @SET_MAKE@ -GSEC_Other_Sources = jrd/isc_file.cpp jrd/ThreadData.cpp jrd/enc.cpp \ - jrd/sha.cpp jrd/guid.cpp +GSEC_Other_Sources = jrd/isc_file.cpp jrd/ThreadData.cpp GSEC_Files = gsec.cpp call_service.cpp gsecMain.cpp security.cpp GSEC_Sources = $(addprefix utilities/gsec/, $(GSEC_Files)) $(GSEC_Other_Sources) GSEC_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(GSEC_Sources)))) diff --git a/builds/posix/Makefile.in.embed.util b/builds/posix/Makefile.in.embed.util index 5e4b4596a5..6d164f592b 100644 --- a/builds/posix/Makefile.in.embed.util +++ b/builds/posix/Makefile.in.embed.util @@ -70,7 +70,7 @@ DROP_Sources = $(addprefix utilities/, $(DROP_Files)) $(DROP_Other_Sources) DROP_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(DROP_Sources)))) $(FBCOMMON_ClientObjects) -GSEC_Other_Sources = jrd/enc.cpp jrd/sha.cpp jrd/guid.cpp \ +GSEC_Other_Sources = \ jrd/isc_file.cpp common/config/config.cpp common/config/config_file.cpp \ common/config/ConfigCache.cpp common/config/dir_list.cpp \ jrd/ThreadData.cpp $(OS_SPECIFIC_Sources) diff --git a/builds/posix/Makefile.in.fbserver b/builds/posix/Makefile.in.fbserver index 1c62c7e4d3..62c864ae6d 100644 --- a/builds/posix/Makefile.in.fbserver +++ b/builds/posix/Makefile.in.fbserver @@ -39,9 +39,14 @@ include $(ROOT)/gen/make.shared.variables @SET_MAKE@ +SERVER_Other_sources = jrd/pwd.cpp jrd/sha.cpp +SERVER_Other Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(SERVER_Other_sources)))) + SERVER_Files = $(OS_ServerFiles) server.cpp -SERVER_Sources = $(addprefix remote/, $(SERVER_Files)) jrd/pwd.cpp -SERVER_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(SERVER_Sources)))) $(LIBFBSERVER_Objects) $(COMMON_Objects) +SERVER_Sources = $(addprefix remote/, $(SERVER_Files)) +SERVER_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(SERVER_Sources)))) \ + $(LIBFBSERVER_Objects) $(COMMON_Objects) $(SERVER_Other Objects) + .PHONY: fbserver diff --git a/builds/posix/Makefile.in.firebird b/builds/posix/Makefile.in.firebird index cad07e2397..db66a7e477 100644 --- a/builds/posix/Makefile.in.firebird +++ b/builds/posix/Makefile.in.firebird @@ -134,7 +134,7 @@ CPU_OPTION = -j$(CPU) .PHONY: all firebird firebird_boot firebird_basic .PHONY: firebird_embedded firebird_server classic_programs super_programs .PHONY: firebird_super firebird_classic btyacc_binary -.PHONY: fbtrace +.PHONY: plugins2 # The main targets are firebird_embedded or firebird_server @@ -145,8 +145,8 @@ CPU_OPTION = -j$(CPU) firebird : firebird_@FIREBIRD_ARCH_TYPE@ $(PLATFORM_POSTBUILD_TARGET) -firebird_classic firebird_embedded: firebird_basic classic_targets fbtrace -firebird_super firebird_server: firebird_basic super_targets fbtrace +firebird_classic firebird_embedded: firebird_basic classic_targets plugins2 +firebird_super firebird_server: firebird_basic super_targets plugins2 @@ -414,8 +414,9 @@ client_qli: #--------------------------------------------------------------------------- -fbtrace: +plugins2: $(MAKE) $(CPU_OPTION) -f $(GEN_ROOT)/Makefile.fbtrace + $(MAKE) $(CPU_OPTION) -f $(GEN_ROOT)/Makefile.user.management #--------------------------------------------------------------------------- diff --git a/builds/posix/Makefile.in.smp_server b/builds/posix/Makefile.in.smp_server index 5c88b484b6..98a096798a 100644 --- a/builds/posix/Makefile.in.smp_server +++ b/builds/posix/Makefile.in.smp_server @@ -42,8 +42,8 @@ include $(ROOT)/gen/make.shared.variables SERVER_JrdFiles = ThreadData.cpp divorce.cpp dsc.cpp enc.cpp isc_file.cpp isc.cpp \ sdl.cpp status.cpp SERVER_Files = $(OS_ServerFiles) server.cpp -SERVER_Other_sources = common/cvt.cpp common/classes/DbImplementation.cpp \ -jrd/pwd.cpp jrd/sha.cpp jrd/guid.cpp auth/Auth.cpp +SERVER_Other_sources = common/cvt.cpp common/classes/DbImplementation.cpp auth/Auth.cpp \ +jrd/pwd.cpp jrd/sha.cpp jrd/guid.cpp SERVER_Sources = $(addprefix remote/, $(SERVER_Files)) $(addprefix jrd/, $(SERVER_JrdFiles)) $(SERVER_Other_sources) REMOTE_CommonSources = $(addprefix remote/, $(REMOTE_CommonFiles)) diff --git a/builds/posix/Makefile.in.user.management b/builds/posix/Makefile.in.user.management new file mode 100644 index 0000000000..8282e04b11 --- /dev/null +++ b/builds/posix/Makefile.in.user.management @@ -0,0 +1,81 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# You may obtain a copy of the Licence at +# http://www.gnu.org/licences/lgpl.html +# +# As a special exception this file can also be included in modules +# with other source code as long as that source code has been +# released under an Open Source Initiative certificed licence. +# More information about OSI certification can be found at: +# http://www.opensource.org +# +# This module is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public Licence for more details. +# +# This module was created by members of the firebird development +# team. All individual contributions remain the Copyright (C) of +# those individuals and all rights are reserved. Contributors to +# this file are either listed below or can be obtained from a CVS +# history command. +# +# Created by: Mark O'Donohue +# +# Contributor(s): +# +# +# +ROOT=.. +ObjModuleType=std + +include $(ROOT)/gen/make.defaults +include $(ROOT)/gen/make.platform +include $(ROOT)/gen/make.rules +include $(ROOT)/gen/make.shared.variables + +@SET_MAKE@ + + +USER_MANAGEMENT_Files = LegacyManagement.epp + +USER_MANAGEMENT_Sources = $(addprefix auth/SecurityDatabase/, $(USER_MANAGEMENT_Files)) + +USER_MANAGEMENT_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(USER_MANAGEMENT_Sources)))) + + +MANAGEMENT_OTHER_Sources = jrd/enc.cpp jrd/sha.cpp jrd/guid.cpp common/classes/alloc.cpp \ +common/classes/locks.cpp common/classes/UserBlob.cpp common/classes/init.cpp common/classes/fb_string.cpp \ +common/fb_exception.cpp common/thd.cpp common/StatusArg.cpp + + +MANAGEMENT_OTHER_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(MANAGEMENT_OTHER_Sources)))) + + +MANAGEMENT_Objects = $(USER_MANAGEMENT_Objects) $(MANAGEMENT_OTHER_Objects) +#$(FBCLASSES_ClientObjects) $(FBCOMMON_ClientObjects) +# $(CONFIG_Objects) \ +# $(FBCLASSES_MsgObjects) \ +# $(FBCONFIG_Objects) + + +AllObjects = $(MANAGEMENT_Objects) +Dependencies = $(AllObjects:.o=.d) + + +.PHONY: all user_management + + +all : user_management + +user_management: $(MANAGEMENT) + +$(MANAGEMENT): $(MANAGEMENT_Objects) + $(LINK_PLUGIN) $(call LIB_LINK_SONAME,$(MANAGEMENT).0) -o $@ $^ $(LINK_PLUG_LIBS) + + +include $(ROOT)/gen/make.shared.targets + +-include $(Dependencies) diff --git a/builds/posix/firebird.vers b/builds/posix/firebird.vers index 5b3d538272..decd45932c 100644 --- a/builds/posix/firebird.vers +++ b/builds/posix/firebird.vers @@ -333,6 +333,11 @@ Bopen fb_shutdown fb_shutdown_callback +# Plugins support + +fb_register_plugin +fb_query_plugin + # Other misc functions isc_ftof diff --git a/builds/posix/make.defaults b/builds/posix/make.defaults index e64f57ef79..8e2eb98637 100755 --- a/builds/posix/make.defaults +++ b/builds/posix/make.defaults @@ -317,6 +317,9 @@ LINK_EMBED = $(LIB_LINK) $(LINK_FIREBIRD_EMBED_SYMBOLS) $(LIB_LINK_OPTIONS) $(LI $(call LIB_LINK_SONAME,$(SharedLibrarySoName)) $(call LIB_LINK_RPATH,lib) LINK_EMBED_LIBS = -L$(LIB) $(LIB_GUI) $(SO_LINK_LIBS) $(ICU_LIBS) +LINK_PLUGIN = $(LIB_LINK) $(LINK_EMPTY_SYMBOLS) $(LIB_LINK_OPTIONS) $(call LIB_LINK_RPATH,lib) +LINK_PLUG_LIBS = -L$(LIB) $(SO_LINK_LIBS) + # From utilities CREATE_DB = $(BIN)/create_db$(EXEC_EXT) GDS_DROP = $(BIN)/gds_drop$(EXEC_EXT) @@ -339,6 +342,7 @@ INSTREG = $(BIN)/instreg$(EXEC_EXT) INSTSVC = $(BIN)/instsvc$(EXEC_EXT) ISC_GDB = $(FIREBIRD)/security2.fdb ISC_GBAK = $(BIN)/security.gbak +MANAGEMENT = $(PLUGINS)/$(LIB_PREFIX)user_management.$(SHRLIB_EXT) # From qli QLI = $(BIN)/qli$(EXEC_EXT) diff --git a/builds/posix/make.rules b/builds/posix/make.rules index 2818028aee..1af3c456a0 100644 --- a/builds/posix/make.rules +++ b/builds/posix/make.rules @@ -127,7 +127,7 @@ $(OBJ)/%.o: $(SRC_ROOT)/%.cpp $(OBJ)/jrd/fun.epp $(OBJ)/jrd/dyn.epp $(OBJ)/jrd/dfw.epp $(OBJ)/jrd/dyn_util.epp \ $(OBJ)/jrd/pcmet.epp $(OBJ)/jrd/met.epp $(OBJ)/jrd/dpm.epp $(OBJ)/utilities/rebuild/rstore.epp \ $(OBJ)/utilities/rebuild/rmet.epp $(OBJ)/utilities/gstat/dba.epp $(OBJ)/utilities/stats.epp \ - $(OBJ)/utilities/gsec/security.epp $(OBJ)/alice/alice_meta.epp $(OBJ)/qli/meta.epp \ + $(OBJ)/auth/SecurityDatabase/LegacyManagement.epp $(OBJ)/alice/alice_meta.epp $(OBJ)/qli/meta.epp \ $(OBJ)/qli/proc.epp $(OBJ)/qli/show.epp $(OBJ)/qli/help.epp $(OBJ)/misc/codes.epp \ $(OBJ)/gpre/gpre_meta.epp $(OBJ)/dsql/blob.epp $(OBJ)/dsql/array.epp \ $(OBJ)/dsql/PackageNodes.epp $(OBJ)/dsql/metd.epp $(OBJ)/dsql/DdlNodes.epp $(OBJ)/isql/show.epp \ diff --git a/builds/posix/make.shared.variables b/builds/posix/make.shared.variables index 60cb325600..e4c7b34ed4 100644 --- a/builds/posix/make.shared.variables +++ b/builds/posix/make.shared.variables @@ -14,7 +14,7 @@ WHY_Sources = why.cpp JRD_ClientFiles = alt.cpp db_alias.cpp dsc.cpp \ - enc.cpp gds.cpp isc.cpp isc_file.cpp isc_ipc.cpp \ + gds.cpp isc.cpp isc_file.cpp isc_ipc.cpp \ perf.cpp sdl.cpp status.cpp \ ThreadData.cpp ThreadStart.cpp utl.cpp \ $(WHY_Sources) @@ -41,7 +41,7 @@ JRD_ServerFiles= blob_filter.cpp cvt.cpp dpm.epp dyn.epp dyn_def.epp \ sdw.cpp shut.cpp sort.cpp sqz.cpp \ svc.cpp SysFunction.cpp TempSpace.cpp tpc.cpp tra.cpp validation.cpp \ ValueImpl.cpp ValuesImpl.cpp vio.cpp \ - nodebug.cpp nbak.cpp sha.cpp $(Physical_IO_Module) TextType.cpp \ + nodebug.cpp nbak.cpp $(Physical_IO_Module) TextType.cpp \ unicode_util.cpp RuntimeStatistics.cpp DebugInterface.cpp \ extds/ExtDS.cpp extds/InternalDS.cpp extds/IscDS.cpp \ trace/TraceConfigStorage.cpp trace/TraceLog.cpp \ @@ -114,7 +114,7 @@ INTERFACE_Files= $(REMOTE_ClientFiles) $(REMOTE_CommonFiles) INTERFACE_Sources = $(addprefix remote/, $(INTERFACE_Files)) \ - auth/Auth.cpp auth/SecurityDatabase/LegacyClient.cpp + auth/Auth.cpp auth/AuthDbg.cpp auth/SecurityDatabase/LegacyClient.cpp jrd/enc.cpp INTERFACE_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(INTERFACE_Sources)))) ifeq ($(PLATFORM),win32) @@ -357,7 +357,7 @@ LIBFBSERVER_Objects =$(LIBFBEMBED_Objects) # MOD 29-July-2002 # Stub for services entrypoints missing in static library -STUB_Sources = jrd/svc_stub.cpp utilities/gsec/security.epp +STUB_Sources = jrd/svc_stub.cpp utilities/gsec/security.cpp STUB_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(STUB_Sources)))) diff --git a/configure.in b/configure.in index e5abff4eb9..1f26b5f2e4 100644 --- a/configure.in +++ b/configure.in @@ -1371,6 +1371,7 @@ gen/Makefile.embed.isql:${MAKE_SRC_DIR}/Makefile.in.embed.isql gen/Makefile.embed.qli:${MAKE_SRC_DIR}/Makefile.in.embed.qli gen/Makefile.embed.gpre:${MAKE_SRC_DIR}/Makefile.in.embed.gpre gen/Makefile.fbtrace:${MAKE_SRC_DIR}/Makefile.in.fbtrace +gen/Makefile.user.management:${MAKE_SRC_DIR}/Makefile.in.user.management gen/Makefile.install:builds/install/arch-specific/${INSTALL_PREFIX}/Makefile.in Makefile:Makefile.in ) diff --git a/src/auth/Auth.cpp b/src/auth/Auth.cpp index 98c3eb8cbd..8b804ef1a8 100644 --- a/src/auth/Auth.cpp +++ b/src/auth/Auth.cpp @@ -28,134 +28,7 @@ #include "firebird.h" #include "../auth/Auth.h" #include "../jrd/ibase.h" - -#ifdef AUTH_DEBUG - -namespace -{ - void debugName(const char** data, unsigned short* dataSize) - { - // Construct a copy of the literal so we don't violate the constness. - // The caller can do anything with the pointer unless we change getName() signature. - static char name[] = "DEBUG_AUTH"; - *data = name; - *dataSize = strlen(name); - } -} - -namespace Auth { - -ServerInstance* DebugServer::instance() -{ - return interfaceAlloc(); -} - -ClientInstance* DebugClient::instance() -{ - return interfaceAlloc(); -} - -void DebugServer::getName(const char** data, unsigned short* dataSize) -{ - debugName(data, dataSize); -} - -void DebugClient::getName(const char** data, unsigned short* dataSize) -{ - debugName(data, dataSize); -} - -void DebugServer::release() -{ - interfaceFree(this); -} - -void DebugClient::release() -{ - interfaceFree(this); -} - -DebugServerInstance::DebugServerInstance() - : str(*getDefaultMemoryPool()) -{ } - -Result DebugServerInstance::startAuthentication(bool isService, const char* dbName, - const unsigned char* dpb, unsigned int dpbSize, - WriterInterface* writerInterface) -{ - str.erase(); - Firebird::ClumpletReader rdr(isService ? - Firebird::ClumpletReader::spbList : - Firebird::ClumpletReader::dpbList, dpb, dpbSize); - - if (rdr.find(isService ? isc_spb_trusted_auth : isc_dpb_trusted_auth)) - { - str.assign(rdr.getBytes(), rdr.getClumpLength()); - } - - str += '_'; - return AUTH_MORE_DATA; -} - -Result DebugServerInstance::contAuthentication(WriterInterface* writerInterface, - const unsigned char* data, unsigned int size) -{ - //fprintf(stderr, "DebugServerInstance::contAuthentication: %.*s\n", size, data); - writerInterface->add(Firebird::string((const char*) data, size).c_str(), "DEBUG", ""); - return AUTH_SUCCESS; -} - -void DebugServerInstance::getData(const unsigned char** data, unsigned short* dataSize) -{ - *data = reinterpret_cast(str.c_str()); - *dataSize = str.length(); - //fprintf(stderr, "DebugServerInstance::getData: %.*s\n", *dataSize, *data); -} - -void DebugServerInstance::release() -{ - interfaceFree(this); -} - -DebugClientInstance::DebugClientInstance() - : str(*getDefaultMemoryPool()) -{ } - -Result DebugClientInstance::startAuthentication(bool isService, const char*, DpbInterface* dpb) -{ - str = "HAND"; - if (dpb) - { - dpb->add(isService ? isc_spb_trusted_auth : isc_dpb_trusted_auth, - str.c_str(), str.length()); - return AUTH_SUCCESS; - } - return AUTH_MORE_DATA; -} - -Result DebugClientInstance::contAuthentication(const unsigned char* data, unsigned int size) -{ - //fprintf(stderr, "DebugClientInstance::contAuthentication: %.*s\n", size, data); - str.assign(data, size); - str += "SHAKE"; - return AUTH_CONTINUE; -} - -void DebugClientInstance::getData(const unsigned char** data, unsigned short* dataSize) -{ - *data = reinterpret_cast(str.c_str()); - *dataSize = str.length(); - //fprintf(stderr, "DebugClientInstance::getData: %.*s\n", *dataSize, *data); -} - -void DebugClientInstance::release() -{ - interfaceFree(this); -} - -} // namespace Auth - -#endif // AUTH_DEBUG +#include "../common/classes/ImplementHelper.h" namespace Auth { @@ -202,16 +75,13 @@ void DpbImplementation::drop() } -bool legacy(Plugin* plugin) +bool legacy(Firebird::Plugin* plugin) { const char* legacyTrusted = "WIN_SSPI"; - const short legLength = strlen(legacyTrusted); - const char* nm; - USHORT len; + const unsigned short legLength = strlen(legacyTrusted); + const char* nm = plugin->name(); - plugin->getName(&nm, &len); - - return len == legLength && memcmp(legacyTrusted, nm, legLength) == 0; + return strlen(nm) == legLength && memcmp(legacyTrusted, nm, legLength) == 0; } } // namespace Auth diff --git a/src/auth/Auth.h b/src/auth/Auth.h index 51dc0c2046..9c36ae7385 100644 --- a/src/auth/Auth.h +++ b/src/auth/Auth.h @@ -38,7 +38,7 @@ namespace Auth { -bool legacy(Plugin* plugin); +bool legacy(Firebird::Plugin* plugin); class WriterImplementation : public WriterInterface, public Firebird::PermanentStorage { @@ -69,7 +69,7 @@ private: Firebird::ClumpletWriter* body; }; -//#define AUTH_DEBUG +#define AUTH_DEBUG #ifdef AUTH_DEBUG @@ -80,7 +80,6 @@ class DebugServer : public ServerPlugin { public: ServerInstance* instance(); - void getName(const char** data, unsigned short* dataSize); void release(); }; @@ -88,7 +87,6 @@ class DebugClient : public ClientPlugin { public: ClientInstance* instance(); - void getName(const char** data, unsigned short* dataSize); void release(); }; diff --git a/src/auth/AuthDbg.cpp b/src/auth/AuthDbg.cpp new file mode 100644 index 0000000000..55f477e80a --- /dev/null +++ b/src/auth/AuthDbg.cpp @@ -0,0 +1,133 @@ +/* + * PROGRAM: Firebird authentication + * MODULE: Auth.cpp + * DESCRIPTION: Implementation of interfaces, passed to plugins + * Plugins loader + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2010 Alex Peshkov + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include "firebird.h" +#include "../auth/AuthDbg.h" +#include "../jrd/ibase.h" +#include "../common/classes/ImplementHelper.h" + +#ifdef AUTH_DEBUG + +namespace { + char name[] = "DEBUG_AUTH"; + Firebird::PluginHelper debugServer; + Firebird::PluginHelper debugClient; +} + +namespace Auth { + +ServerInstance* DebugServer::instance() +{ + return Firebird::interfaceAlloc(); +} + +ClientInstance* DebugClient::instance() +{ + return Firebird::interfaceAlloc(); +} + +DebugServerInstance::DebugServerInstance() + : str(*getDefaultMemoryPool()) +{ } + +Result DebugServerInstance::startAuthentication(bool isService, const char* dbName, + const unsigned char* dpb, unsigned int dpbSize, + WriterInterface* writerInterface) +{ + str.erase(); + Firebird::ClumpletReader rdr(isService ? + Firebird::ClumpletReader::spbList : + Firebird::ClumpletReader::dpbList, dpb, dpbSize); + + if (rdr.find(isService ? isc_spb_trusted_auth : isc_dpb_trusted_auth)) + { + str.assign(rdr.getBytes(), rdr.getClumpLength()); + } + + str += '_'; + return AUTH_MORE_DATA; +} + +Result DebugServerInstance::contAuthentication(WriterInterface* writerInterface, + const unsigned char* data, unsigned int size) +{ + //fprintf(stderr, "DebugServerInstance::contAuthentication: %.*s\n", size, data); + writerInterface->add(Firebird::string((const char*) data, size).c_str(), "DEBUG", ""); + return AUTH_SUCCESS; +} + +void DebugServerInstance::getData(const unsigned char** data, unsigned short* dataSize) +{ + *data = reinterpret_cast(str.c_str()); + *dataSize = str.length(); + //fprintf(stderr, "DebugServerInstance::getData: %.*s\n", *dataSize, *data); +} + +void DebugServerInstance::release() +{ + Firebird::interfaceFree(this); +} + +DebugClientInstance::DebugClientInstance() + : str(*getDefaultMemoryPool()) +{ } + +Result DebugClientInstance::startAuthentication(bool isService, const char*, DpbInterface* dpb) +{ + str = "HAND"; + if (dpb) + { + dpb->add(isService ? isc_spb_trusted_auth : isc_dpb_trusted_auth, + str.c_str(), str.length()); + return AUTH_SUCCESS; + } + return AUTH_MORE_DATA; +} + +Result DebugClientInstance::contAuthentication(const unsigned char* data, unsigned int size) +{ + //fprintf(stderr, "DebugClientInstance::contAuthentication: %.*s\n", size, data); + str.assign(data, size); + str += "SHAKE"; + return AUTH_CONTINUE; +} + +void DebugClientInstance::getData(const unsigned char** data, unsigned short* dataSize) +{ + *data = reinterpret_cast(str.c_str()); + *dataSize = str.length(); + //fprintf(stderr, "DebugClientInstance::getData: %.*s\n", *dataSize, *data); +} + +void DebugClientInstance::release() +{ + Firebird::interfaceFree(this); +} + +} // namespace Auth + +#endif // AUTH_DEBUG diff --git a/src/auth/AuthDbg.h b/src/auth/AuthDbg.h new file mode 100644 index 0000000000..7dfec3e62c --- /dev/null +++ b/src/auth/AuthDbg.h @@ -0,0 +1,95 @@ +/* + * PROGRAM: Firebird authentication + * MODULE: Auth.h + * DESCRIPTION: Implementation of interfaces, passed to plugins + * Plugins loader + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2010 Alex Peshkov + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + * + * + */ + +#ifndef FB_AUTHDBG_H +#define FB_AUTHDBG_H + +//#define AUTH_DEBUG + +#ifdef AUTH_DEBUG + +#include "../auth/AuthInterface.h" +#include "../common/classes/ClumpletWriter.h" +#include "../common/classes/init.h" +#include "../common/classes/array.h" +#include "../common/classes/fb_string.h" + +namespace Auth { + +// The idea of debug plugin is to send some data from server to client, +// modify them on client and return result (which becomes login name) to the server + +class DebugServer : public ServerPlugin +{ +public: + ServerInstance* instance(); +}; + +class DebugClient : public ClientPlugin +{ +public: + ClientInstance* instance(); +}; + +class DebugServerInstance : public ServerInstance +{ +public: + DebugServerInstance(); + + Result startAuthentication(bool isService, const char* dbName, + const unsigned char* dpb, unsigned int dpbSize, + WriterInterface* writerInterface); + Result contAuthentication(WriterInterface* writerInterface, + const unsigned char* data, unsigned int size); + void getData(const unsigned char** data, unsigned short* dataSize); + void release(); + +private: + Firebird::string str; +}; + +class DebugClientInstance : public ClientInstance +{ +public: + DebugClientInstance(); + + Result startAuthentication(bool isService, const char* dbName, DpbInterface* dpb); + Result contAuthentication(const unsigned char* data, unsigned int size); + void getData(const unsigned char** data, unsigned short* dataSize); + void release(); + +private: + Firebird::string str; +}; + +} // namespace Auth + +#endif // AUTH_DEBUG + +#endif // FB_AUTHDBG_H diff --git a/src/auth/AuthInterface.h b/src/auth/AuthInterface.h index 6b25e58092..245a5c844f 100644 --- a/src/auth/AuthInterface.h +++ b/src/auth/AuthInterface.h @@ -31,14 +31,14 @@ #include "../common/classes/Interface.h" +// This is temporal measure - see later +struct internal_user_data; +#include "../utilities/gsec/secur_proto.h" + namespace Auth { enum Result {AUTH_SUCCESS, AUTH_CONTINUE, AUTH_FAILED, AUTH_MORE_DATA}; -class InterfaceBase : public Firebird::Interface -{ -}; - class WriterInterface { public: @@ -54,13 +54,7 @@ public: virtual void drop() = 0; }; -class Plugin : public InterfaceBase -{ -public: - virtual void getName(const char** data, unsigned short* dataSize) = 0; -}; - -class ServerInstance : public InterfaceBase +class ServerInstance : public Firebird::Interface { public: virtual Result startAuthentication(bool isService, const char* dbName, @@ -71,13 +65,13 @@ public: virtual void getData(const unsigned char** data, unsigned short* dataSize) = 0; }; -class ServerPlugin : public Plugin +class ServerPlugin : public Firebird::Plugin { public: virtual ServerInstance* instance() = 0; }; -class ClientInstance : public InterfaceBase +class ClientInstance : public Firebird::Interface { public: virtual Result startAuthentication(bool isService, const char* dbName, DpbInterface* dpb) = 0; @@ -85,12 +79,22 @@ public: virtual void getData(const unsigned char** data, unsigned short* dataSize) = 0; }; -class ClientPlugin : public Plugin +class ClientPlugin : public Firebird::Plugin { public: virtual ClientInstance* instance() = 0; }; +class ManagementPlugin : public Firebird::Plugin +{ +public: + // work in progress - we must avoid both internal_user_data and callback function + virtual int execLine(ISC_STATUS* isc_status, const char *realUser, + FB_API_HANDLE db, FB_API_HANDLE trans, + internal_user_data* io_user_data, + FPTR_SECURITY_CALLBACK display_func, void* callback_arg) = 0; +}; + } // namespace Auth diff --git a/src/auth/SecurityDatabase/LegacyClient.cpp b/src/auth/SecurityDatabase/LegacyClient.cpp index 87332f03ed..162db78161 100644 --- a/src/auth/SecurityDatabase/LegacyClient.cpp +++ b/src/auth/SecurityDatabase/LegacyClient.cpp @@ -28,6 +28,12 @@ #include "firebird.h" #include "../jrd/ibase.h" #include "../auth/SecurityDatabase/LegacyClient.h" +#include "../common/classes/ImplementHelper.h" + +namespace { + char name[] = "LEGACY_AUTH"; + Firebird::PluginHelper client; +} namespace Auth { @@ -36,19 +42,6 @@ ClientInstance* SecurityDatabaseClient::instance() return Firebird::interfaceAlloc(); } -void SecurityDatabaseClient::getName(const char** data, unsigned short* dataSize) -{ - // Do not violate the constness. - static char name[] = "LEGACY_AUTH"; - *data = name; - *dataSize = strlen(name); -} - -void SecurityDatabaseClient::release() -{ - interfaceFree(this); -} - Result SecurityDatabaseClientInstance::startAuthentication(bool, const char*, DpbInterface* dpb) { return dpb->find(isc_dpb_user_name) && diff --git a/src/auth/SecurityDatabase/LegacyClient.h b/src/auth/SecurityDatabase/LegacyClient.h index fe43e59716..b416762297 100644 --- a/src/auth/SecurityDatabase/LegacyClient.h +++ b/src/auth/SecurityDatabase/LegacyClient.h @@ -38,8 +38,6 @@ class SecurityDatabaseClient : public ClientPlugin { public: ClientInstance* instance(); - void getName(const char** data, unsigned short* dataSize); - void release(); }; class SecurityDatabaseClientInstance : public ClientInstance diff --git a/src/utilities/gsec/security.epp b/src/auth/SecurityDatabase/LegacyManagement.epp similarity index 67% rename from src/utilities/gsec/security.epp rename to src/auth/SecurityDatabase/LegacyManagement.epp index 7490efcfd0..3c6aef3493 100644 --- a/src/utilities/gsec/security.epp +++ b/src/auth/SecurityDatabase/LegacyManagement.epp @@ -23,6 +23,7 @@ */ #include "firebird.h" +#include "../common/classes/alloc.h" #include #include #include @@ -34,16 +35,23 @@ #include "../jrd/gds_proto.h" #include "../jrd/isc_proto.h" #include "../utilities/gsec/gsec.h" -#include "../utilities/gsec/secur_proto.h" #include "../common/utils_proto.h" #include "../common/classes/init.h" #include "../common/classes/UserBlob.h" +#include "../auth/SecurityDatabase/LegacyManagement.h" +#include "../common/classes/ImplementHelper.h" DATABASE DB = STATIC FILENAME "security2.fdb"; -static Firebird::GlobalPtr execLineMutex; // protects various gpre generated structures +namespace { -static bool grantRevokeAdmin(ISC_STATUS* isc_status, FB_API_HANDLE DB, FB_API_HANDLE trans, +Firebird::GlobalPtr execLineMutex; // protects various gpre generated structures + +// register plugin +char name[] = "LEGACY_AUTH"; +Firebird::PluginHelper manage; + +bool grantRevokeAdmin(ISC_STATUS* isc_status, FB_API_HANDLE DB, FB_API_HANDLE trans, const internal_user_data* io_user_data) { if (!io_user_data->admin_entered) @@ -84,8 +92,8 @@ static bool grantRevokeAdmin(ISC_STATUS* isc_status, FB_API_HANDLE DB, FB_API_HA return isc_status[1] == 0; } - -static bool storePasswd(ISC_STATUS* isc_status, FB_API_HANDLE DB, FB_API_HANDLE trans, +/* +bool storePasswd(ISC_STATUS* isc_status, FB_API_HANDLE DB, FB_API_HANDLE trans, ISC_QUAD& blobId, const Firebird::string& passwd) { UserBlob blob(isc_status); @@ -98,15 +106,21 @@ static bool storePasswd(ISC_STATUS* isc_status, FB_API_HANDLE DB, FB_API_HANDLE if (!blob.putData(passwd.length(), passwd.c_str())) { - blob.close(); return false; } return blob.close(); } + */ -SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, - const char* realUser, +} // anonymous namespace + +namespace Auth { + +// work in progress - we must avoid both internal_user_data and callback function + +int SecurityDatabaseManagement::execLine(ISC_STATUS* isc_status, + const char *realUser, FB_API_HANDLE DB, FB_API_HANDLE trans, internal_user_data* io_user_data, @@ -178,7 +192,7 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, SCHAR encrypted1[Auth::MAX_PASSWORD_LENGTH + 2]; Firebird::string encrypted2; bool found; - SSHORT ret = 0; + int ret = 0; // check for non-printable characters in user name for (const TEXT* p = io_user_data->user_name; *p; p++) @@ -220,63 +234,59 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, // this checks the "entered" flags for each parameter (except the name) // and makes all non-entered parameters null valued - STORE (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS USING - strcpy(U.RDB$USER_NAME, io_user_data->user_name); + STORE (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN PLG$USERS USING + strcpy(U.PLG$USER_NAME, io_user_data->user_name); if (io_user_data->uid_entered) { - U.RDB$UID = io_user_data->uid; - U.RDB$UID.NULL = ISC_FALSE; + U.PLG$UID = io_user_data->uid; + U.PLG$UID.NULL = ISC_FALSE; } else - U.RDB$UID.NULL = ISC_TRUE; + U.PLG$UID.NULL = ISC_TRUE; if (io_user_data->gid_entered) { - U.RDB$GID = io_user_data->gid; - U.RDB$GID.NULL = ISC_FALSE; + U.PLG$GID = io_user_data->gid; + U.PLG$GID.NULL = ISC_FALSE; } else - U.RDB$GID.NULL = ISC_TRUE; + U.PLG$GID.NULL = ISC_TRUE; if (io_user_data->group_name_entered) { - strcpy(U.RDB$GROUP_NAME, io_user_data->group_name); - U.RDB$GROUP_NAME.NULL = ISC_FALSE; + strcpy(U.PLG$GROUP_NAME, io_user_data->group_name); + U.PLG$GROUP_NAME.NULL = ISC_FALSE; } else - U.RDB$GROUP_NAME.NULL = ISC_TRUE; + U.PLG$GROUP_NAME.NULL = ISC_TRUE; if (io_user_data->password_entered) { ENC_crypt(encrypted1, sizeof encrypted1, io_user_data->password, Auth::PASSWORD_SALT); Auth::SecurityDatabase::hash(encrypted2, io_user_data->user_name, &encrypted1[2]); - if (!storePasswd(isc_status, DB, trans, U.RDB$PASSWD, encrypted2)) - { - ret = GsecMsg19; - break; - } - U.RDB$PASSWD.NULL = ISC_FALSE; + strcpy(U.PLG$PASSWD, encrypted2.c_str()); + U.PLG$PASSWD.NULL = ISC_FALSE; } else - U.RDB$PASSWD.NULL = ISC_TRUE; + U.PLG$PASSWD.NULL = ISC_TRUE; if (io_user_data->first_name_entered) { - strcpy(U.RDB$FIRST_NAME, io_user_data->first_name); - U.RDB$FIRST_NAME.NULL = ISC_FALSE; + strcpy(U.PLG$FIRST_NAME, io_user_data->first_name); + U.PLG$FIRST_NAME.NULL = ISC_FALSE; } else - U.RDB$FIRST_NAME.NULL = ISC_TRUE; + U.PLG$FIRST_NAME.NULL = ISC_TRUE; if (io_user_data->middle_name_entered) { - strcpy(U.RDB$MIDDLE_NAME, io_user_data->middle_name); - U.RDB$MIDDLE_NAME.NULL = ISC_FALSE; + strcpy(U.PLG$MIDDLE_NAME, io_user_data->middle_name); + U.PLG$MIDDLE_NAME.NULL = ISC_FALSE; } else - U.RDB$MIDDLE_NAME.NULL = ISC_TRUE; + U.PLG$MIDDLE_NAME.NULL = ISC_TRUE; if (io_user_data->last_name_entered) { - strcpy(U.RDB$LAST_NAME, io_user_data->last_name); - U.RDB$LAST_NAME.NULL = ISC_FALSE; + strcpy(U.PLG$LAST_NAME, io_user_data->last_name); + U.PLG$LAST_NAME.NULL = ISC_FALSE; } else - U.RDB$LAST_NAME.NULL = ISC_TRUE; + U.PLG$LAST_NAME.NULL = ISC_TRUE; END_STORE ON_ERROR ret = GsecMsg19; // gsec - add record error @@ -299,65 +309,61 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, // changes the current value to the null value found = false; - FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS - WITH U.RDB$USER_NAME EQ io_user_data->user_name + FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN PLG$USERS + WITH U.PLG$USER_NAME EQ io_user_data->user_name found = true; MODIFY U USING if (io_user_data->uid_entered) { - U.RDB$UID = io_user_data->uid; - U.RDB$UID.NULL = ISC_FALSE; + U.PLG$UID = io_user_data->uid; + U.PLG$UID.NULL = ISC_FALSE; } else if (io_user_data->uid_specified) - U.RDB$UID.NULL = ISC_TRUE; + U.PLG$UID.NULL = ISC_TRUE; if (io_user_data->gid_entered) { - U.RDB$GID = io_user_data->gid; - U.RDB$GID.NULL = ISC_FALSE; + U.PLG$GID = io_user_data->gid; + U.PLG$GID.NULL = ISC_FALSE; } else if (io_user_data->gid_specified) - U.RDB$GID.NULL = ISC_TRUE; + U.PLG$GID.NULL = ISC_TRUE; if (io_user_data->group_name_entered) { - strcpy(U.RDB$GROUP_NAME, io_user_data->group_name); - U.RDB$GROUP_NAME.NULL = ISC_FALSE; + strcpy(U.PLG$GROUP_NAME, io_user_data->group_name); + U.PLG$GROUP_NAME.NULL = ISC_FALSE; } else if (io_user_data->group_name_specified) - U.RDB$GROUP_NAME.NULL = ISC_TRUE; + U.PLG$GROUP_NAME.NULL = ISC_TRUE; if (io_user_data->password_entered) { ENC_crypt(encrypted1, sizeof encrypted1, io_user_data->password, Auth::PASSWORD_SALT); Auth::SecurityDatabase::hash(encrypted2, io_user_data->user_name, &encrypted1[2]); - if (!storePasswd(isc_status, DB, trans, U.RDB$PASSWD, encrypted2)) - { - ret = GsecMsg21; - break; - } - U.RDB$PASSWD.NULL = ISC_FALSE; + strcpy(U.PLG$PASSWD, encrypted2.c_str()); + U.PLG$PASSWD.NULL = ISC_FALSE; } else if (io_user_data->password_specified) - U.RDB$PASSWD.NULL = ISC_TRUE; + U.PLG$PASSWD.NULL = ISC_TRUE; if (io_user_data->first_name_entered) { - strcpy(U.RDB$FIRST_NAME, io_user_data->first_name); - U.RDB$FIRST_NAME.NULL = ISC_FALSE; + strcpy(U.PLG$FIRST_NAME, io_user_data->first_name); + U.PLG$FIRST_NAME.NULL = ISC_FALSE; } else if (io_user_data->first_name_specified) - U.RDB$FIRST_NAME.NULL = ISC_TRUE; + U.PLG$FIRST_NAME.NULL = ISC_TRUE; if (io_user_data->middle_name_entered) { - strcpy(U.RDB$MIDDLE_NAME, io_user_data->middle_name); - U.RDB$MIDDLE_NAME.NULL = ISC_FALSE; + strcpy(U.PLG$MIDDLE_NAME, io_user_data->middle_name); + U.PLG$MIDDLE_NAME.NULL = ISC_FALSE; } else if (io_user_data->middle_name_specified) - U.RDB$MIDDLE_NAME.NULL = ISC_TRUE; + U.PLG$MIDDLE_NAME.NULL = ISC_TRUE; if (io_user_data->last_name_entered) { - strcpy(U.RDB$LAST_NAME, io_user_data->last_name); - U.RDB$LAST_NAME.NULL = ISC_FALSE; + strcpy(U.PLG$LAST_NAME, io_user_data->last_name); + U.PLG$LAST_NAME.NULL = ISC_FALSE; } else if (io_user_data->last_name_specified) - U.RDB$LAST_NAME.NULL = ISC_TRUE; + U.PLG$LAST_NAME.NULL = ISC_TRUE; END_MODIFY ON_ERROR ret = GsecMsg20; @@ -389,8 +395,8 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, ret = GsecMsg23; else { - FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS - WITH U.RDB$USER_NAME EQ io_user_data->user_name + FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN PLG$USERS + WITH U.PLG$USER_NAME EQ io_user_data->user_name found = true; ERASE U ON_ERROR @@ -439,27 +445,27 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, found = false; if (!io_user_data->user_name_entered) { - FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS - io_user_data->uid = U.RDB$UID; - io_user_data->uid_entered = !U.RDB$UID.NULL; - io_user_data->gid = U.RDB$GID; - io_user_data->gid_entered = !U.RDB$GID.NULL; - strcpy(io_user_data->user_name, U.RDB$USER_NAME); - io_user_data->user_name_entered = !U.RDB$USER_NAME.NULL; - strcpy(io_user_data->group_name, U.RDB$GROUP_NAME); - io_user_data->group_name_entered = !U.RDB$GROUP_NAME.NULL; + FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN PLG$USERS + io_user_data->uid = U.PLG$UID; + io_user_data->uid_entered = !U.PLG$UID.NULL; + io_user_data->gid = U.PLG$GID; + io_user_data->gid_entered = !U.PLG$GID.NULL; + strcpy(io_user_data->user_name, U.PLG$USER_NAME); + io_user_data->user_name_entered = !U.PLG$USER_NAME.NULL; + strcpy(io_user_data->group_name, U.PLG$GROUP_NAME); + io_user_data->group_name_entered = !U.PLG$GROUP_NAME.NULL; io_user_data->password[0] = 0; io_user_data->password_entered = false; - strcpy(io_user_data->first_name, U.RDB$FIRST_NAME); - io_user_data->first_name_entered = !U.RDB$FIRST_NAME.NULL; - strcpy(io_user_data->middle_name, U.RDB$MIDDLE_NAME); - io_user_data->middle_name_entered = !U.RDB$MIDDLE_NAME.NULL; - strcpy(io_user_data->last_name, U.RDB$LAST_NAME); - io_user_data->last_name_entered = !U.RDB$LAST_NAME.NULL; + strcpy(io_user_data->first_name, U.PLG$FIRST_NAME); + io_user_data->first_name_entered = !U.PLG$FIRST_NAME.NULL; + strcpy(io_user_data->middle_name, U.PLG$MIDDLE_NAME); + io_user_data->middle_name_entered = !U.PLG$MIDDLE_NAME.NULL; + strcpy(io_user_data->last_name, U.PLG$LAST_NAME); + io_user_data->last_name_entered = !U.PLG$LAST_NAME.NULL; io_user_data->admin = 0; FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request2) P IN RDB$USER_PRIVILEGES - WITH P.RDB$USER EQ U.RDB$USER_NAME + WITH P.RDB$USER EQ U.PLG$USER_NAME AND P.RDB$RELATION_NAME EQ 'RDB$ADMIN' AND P.RDB$PRIVILEGE EQ 'M' io_user_data->admin = 1; @@ -475,28 +481,28 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, } else { - FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS - WITH U.RDB$USER_NAME EQ io_user_data->user_name - io_user_data->uid = U.RDB$UID; - io_user_data->uid_entered = !U.RDB$UID.NULL; - io_user_data->gid = U.RDB$GID; - io_user_data->gid_entered = !U.RDB$GID.NULL; - strcpy(io_user_data->user_name, U.RDB$USER_NAME); - io_user_data->user_name_entered = !U.RDB$USER_NAME.NULL; - strcpy(io_user_data->group_name, U.RDB$GROUP_NAME); - io_user_data->group_name_entered = !U.RDB$GROUP_NAME.NULL; + FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN PLG$USERS + WITH U.PLG$USER_NAME EQ io_user_data->user_name + io_user_data->uid = U.PLG$UID; + io_user_data->uid_entered = !U.PLG$UID.NULL; + io_user_data->gid = U.PLG$GID; + io_user_data->gid_entered = !U.PLG$GID.NULL; + strcpy(io_user_data->user_name, U.PLG$USER_NAME); + io_user_data->user_name_entered = !U.PLG$USER_NAME.NULL; + strcpy(io_user_data->group_name, U.PLG$GROUP_NAME); + io_user_data->group_name_entered = !U.PLG$GROUP_NAME.NULL; io_user_data->password[0] = 0; io_user_data->password_entered = false; - strcpy(io_user_data->first_name, U.RDB$FIRST_NAME); - io_user_data->first_name_entered = !U.RDB$FIRST_NAME.NULL; - strcpy(io_user_data->middle_name, U.RDB$MIDDLE_NAME); - io_user_data->middle_name_entered = !U.RDB$MIDDLE_NAME.NULL; - strcpy(io_user_data->last_name, U.RDB$LAST_NAME); - io_user_data->last_name_entered = !U.RDB$LAST_NAME.NULL; + strcpy(io_user_data->first_name, U.PLG$FIRST_NAME); + io_user_data->first_name_entered = !U.PLG$FIRST_NAME.NULL; + strcpy(io_user_data->middle_name, U.PLG$MIDDLE_NAME); + io_user_data->middle_name_entered = !U.PLG$MIDDLE_NAME.NULL; + strcpy(io_user_data->last_name, U.PLG$LAST_NAME); + io_user_data->last_name_entered = !U.PLG$LAST_NAME.NULL; io_user_data->admin = 0; FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request2) P IN RDB$USER_PRIVILEGES - WITH P.RDB$USER EQ U.RDB$USER_NAME + WITH P.RDB$USER EQ U.PLG$USER_NAME AND P.RDB$RELATION_NAME EQ 'RDB$ADMIN' AND P.RDB$PRIVILEGE EQ 'M' io_user_data->admin = 1; @@ -544,38 +550,4 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, return ret; } -SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, - const char* realUser, - FB_API_HANDLE DB, - internal_user_data* io_user_data, - FPTR_SECURITY_CALLBACK display_func, - void* callback_arg) -{ - FB_API_HANDLE gds_trans = 0; - - START_TRANSACTION - ON_ERROR - return GsecMsg75; // gsec error - END_ERROR; - - SSHORT ret = SECURITY_exec_line(isc_status, realUser, DB, gds_trans, io_user_data, display_func, callback_arg); - - // rollback if we have an error using tmp_status to avoid - // overwriting the error status which the caller wants to see - - if (ret) - { - ISC_STATUS_ARRAY tmp_status; - isc_rollback_transaction(tmp_status, &gds_trans); - } - else - { - COMMIT - ON_ERROR - // CVC: Shouldn't we call isc_rollback_transaction() here? - return GsecMsg75; // gsec error - END_ERROR; - } - - return ret; -} +} // namespace Auth diff --git a/src/auth/SecurityDatabase/LegacyManagement.h b/src/auth/SecurityDatabase/LegacyManagement.h new file mode 100644 index 0000000000..960d51b6c8 --- /dev/null +++ b/src/auth/SecurityDatabase/LegacyManagement.h @@ -0,0 +1,47 @@ +/* + * PROGRAM: Firebird authentication + * MODULE: LegacyManagement.h + * DESCRIPTION: Performs legacy actions with security database + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2010 Alex Peshkov + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#ifndef AUTH_LEGACY_MANAGEMENT_H +#define AUTH_LEGACY_MANAGEMENT_H + +#include "../auth/AuthInterface.h" + + +namespace Auth { + +class SecurityDatabaseManagement : public ManagementPlugin +{ +public: + // work in progress - we must avoid both internal_user_data and callback function + int execLine(ISC_STATUS* isc_status, const char *realUser, + FB_API_HANDLE db, FB_API_HANDLE trans, + internal_user_data* io_user_data, + FPTR_SECURITY_CALLBACK display_func, void* callback_arg); +}; + +} // namespace Auth + +#endif // AUTH_LEGACY_MANAGEMENT_H diff --git a/src/common/classes/ImplementHelper.h b/src/common/classes/ImplementHelper.h new file mode 100644 index 0000000000..4905f08b65 --- /dev/null +++ b/src/common/classes/ImplementHelper.h @@ -0,0 +1,107 @@ +/* + * PROGRAM: Firebird interface. + * MODULE: ImplementHelper.h + * DESCRIPTION: Tools to help write plugins. + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2010 Alex Peshkov + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + * + * + */ + +#ifndef FB_COMMON_CLASSES_IMPLEMENT_HELPER +#define FB_COMMON_CLASSES_IMPLEMENT_HELPER + +#include "../common/classes/Interface.h" + +//#include "../jrd/gds_proto.h" +#include "../common/classes/alloc.h" + +namespace Firebird { + +// If you need interface on stack, use it in template AutoPtr +// as second parameter +class AutoInterface +{ +public: + static void clear(Interface* ptr) + { + if (ptr) + { + ptr->release(); + } + } +}; + +template +T* interfaceAlloc() +{ + /*** + void* ptr = gds__alloc(sizeof(T)); + return new(ptr) T; + ***/ + return FB_NEW(*getDefaultMemoryPool()) T; +} + +template +void interfaceFree(T* ptr) +{ + /*** + delete((void*) 0) ptr; + gds__free(ptr); + ***/ + delete ptr; +} + +// Template to create statis instance of plugin +template +class PluginHelper : public C +{ +public: + PluginHelper() + { + fb_register_plugin(this); + } + virtual const char* name() const + { + return NM; + } + virtual unsigned int type() const + { + return T; + } + + virtual void link(Plugin* chain) + { + pp = chain; + } + virtual Plugin* next() const + { + return pp; + } + +private: + Plugin* pp; +}; + +} // namespace Firebird + + +#endif // FB_COMMON_CLASSES_IMPLEMENT_HELPER diff --git a/src/common/classes/Interface.h b/src/common/classes/Interface.h index f9b11720a6..57bd3f6d7d 100644 --- a/src/common/classes/Interface.h +++ b/src/common/classes/Interface.h @@ -29,11 +29,9 @@ #ifndef FB_COMMON_CLASSES_INTERFACE #define FB_COMMON_CLASSES_INTERFACE -//#include "../jrd/gds_proto.h" -#include "../common/classes/alloc.h" - namespace Firebird { +// Regular interface, typically returned by plugin or other interface class Interface { public: @@ -45,39 +43,31 @@ protected: ~Interface() { } }; -class AutoInterface +// Plugin - single static instance of each plugin is created when plugin library is loaded +class Plugin { public: - static void clear(Interface* ptr) - { - if (ptr) - { - ptr->release(); - } - } + virtual const char* name() const = 0; + virtual unsigned int type() const = 0; + + virtual void link(Plugin* chain) = 0; + virtual Plugin* next() const = 0; + +// static const unsigned int YValve = 1; +// static const unsigned int Engine = 2; +// static const unsigned int Redirector = 3; + static const unsigned int AuthServer = 4; + static const unsigned int AuthClient = 5; + static const unsigned int UserManagement = 6; }; -template -T* interfaceAlloc() +} // namespace Firebird + +extern "C" { - /*** - void* ptr = gds__alloc(sizeof(T)); - return new(ptr) T; - ***/ - return FB_NEW(*getDefaultMemoryPool()) T; + // additional API functions + void ISC_EXPORT fb_register_plugin ( Firebird::Plugin* plugin ); + Firebird::Plugin* ISC_EXPORT fb_query_plugin (unsigned int type, const char* name); } -template -void interfaceFree(T* ptr) -{ - /*** - delete((void*) 0) ptr; - gds__free(ptr); - ***/ - delete ptr; -} - -} // namespace Auth - - #endif // FB_COMMON_CLASSES_INTERFACE diff --git a/src/dbs/security.sql b/src/dbs/security.sql index 7729eaf726..d09c3d5947 100644 --- a/src/dbs/security.sql +++ b/src/dbs/security.sql @@ -15,15 +15,36 @@ * * All Rights Reserved. * Contributor(s): ______________________________________. - * + * * 2004.09.14 Alex Peshkoff - security changes, preventing ordinary users * from access to other users crypted passwords and enabling modification * of there own password. Originally suggested by Ivan Prenosil * (see http://www.volny.cz/iprenosil/interbase/ for details). */ +/* Domain definitions */ +CREATE DOMAIN PLG$PASSWD AS VARCHAR(64) CHARACTER SET BINARY; + +COMMIT; + + +/* Table: RDB$USERS */ +CREATE TABLE PLG$USERS ( + PLG$USER_NAME SEC$USER_NAME NOT NULL PRIMARY KEY, + PLG$GROUP_NAME SEC$USER_NAME, + PLG$UID SEC$UID, + PLG$GID SEC$GID, + PLG$PASSWD PLG$PASSWD NOT NULL, + PLG$COMMENT RDB$DESCRIPTION, + PLG$FIRST_NAME SEC$NAME_PART, + PLG$MIDDLE_NAME SEC$NAME_PART, + PLG$LAST_NAME SEC$NAME_PART); + +COMMIT; + + /* Needed record - with PASSWD = random + SHA1 (random + 'SYSDBA' + crypt('masterke')) */ -INSERT INTO RDB$USERS(RDB$USER_NAME, RDB$PASSWD, RDB$FIRST_NAME, RDB$MIDDLE_NAME, RDB$LAST_NAME) +INSERT INTO PLG$USERS(PLG$USER_NAME, PLG$PASSWD, PLG$FIRST_NAME, PLG$MIDDLE_NAME, PLG$LAST_NAME) VALUES ('SYSDBA', 'NLtwcs9LrxLMOYhG0uGM9i6KS7mf3QAKvFVpmRg=', 'Sql', 'Server', 'Administrator'); COMMIT; diff --git a/src/include/FirebirdPluginApi.h b/src/include/FirebirdPluginApi.h index e9f2a401ec..8418a2ddab 100644 --- a/src/include/FirebirdPluginApi.h +++ b/src/include/FirebirdPluginApi.h @@ -100,7 +100,7 @@ public: // Passed to plugin library through entry point FB_PLUGIN_ENTRY_POINT in Firebird initialization. -class Plugin +class ExtEngPlugin { public: virtual int FB_CALL getVersion() = 0; @@ -114,7 +114,7 @@ public: }; -typedef void (*PluginEntryPoint)(Error* error, Plugin* plugin); +typedef void (*PluginEntryPoint)(Error* error, ExtEngPlugin* plugin); } // namespace Firebird diff --git a/src/include/gen/ids.h b/src/include/gen/ids.h index a584677962..a55962c2b7 100644 --- a/src/include/gen/ids.h +++ b/src/include/gen/ids.h @@ -592,21 +592,7 @@ const USHORT f_pkg_desc = 6; -// Relation 43 (RDB$USERS) - - const USHORT f_user_name = 0; - const USHORT f_group_name = 1; - const USHORT f_uid = 2; - const USHORT f_gid = 3; - const USHORT f_passwd_type = 4; - const USHORT f_passwd = 5; - const USHORT f_first_name = 6; - const USHORT f_middle_name = 7; - const USHORT f_last_name = 8; - const USHORT f_user_desc = 9; - - -// Relation 44 (SEC$USERS) +// Relation 43 (SEC$USERS) const USHORT f_sec_user_name = 0; const USHORT f_sec_group_name = 1; diff --git a/src/jrd/PluginManager.h b/src/jrd/PluginManager.h index ad501847b6..89f2175519 100644 --- a/src/jrd/PluginManager.h +++ b/src/jrd/PluginManager.h @@ -40,7 +40,7 @@ namespace Jrd { typedef Firebird::Pair > ConfigEntry; -class PluginImpl : public Firebird::Plugin, public Firebird::GlobalStorage +class PluginImpl : public Firebird::ExtEngPlugin, public Firebird::GlobalStorage { friend class PluginManager; diff --git a/src/jrd/fields.h b/src/jrd/fields.h index afe5d7ad7f..85423f0bc1 100644 --- a/src/jrd/fields.h +++ b/src/jrd/fields.h @@ -167,8 +167,7 @@ FIELD(fld_identity_type , nam_identity_type , dtype_short , sizeof(SSHORT) , 0 , NULL , true) + FIELD(fld_user_name , nam_user_name , dtype_text , MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , true) FIELD(fld_uid , nam_uid , dtype_long , sizeof(SLONG) , 0 , NULL , true) FIELD(fld_gid , nam_gid , dtype_long , sizeof(SLONG) , 0 , NULL , true) - FIELD(fld_passwd_type , nam_passwd_type , dtype_text , 32 , dsc_text_type_ascii , NULL , true) - FIELD(fld_passwd , nam_passwd , dtype_blob , BLOB_SIZE , isc_blob_untyped , NULL , true) FIELD(fld_name_part , nam_name_part , dtype_text , 32 , dsc_text_type_metadata , NULL , true) diff --git a/src/jrd/gds.cpp b/src/jrd/gds.cpp index 3847041a4f..2b609ac211 100644 --- a/src/jrd/gds.cpp +++ b/src/jrd/gds.cpp @@ -55,6 +55,7 @@ #include "../common/classes/locks.h" #include "../common/classes/timestamp.h" #include "../common/classes/init.h" +#include "../common/classes/Interface.h" #include "../common/classes/TempFile.h" #include "../common/utils_proto.h" @@ -3648,7 +3649,6 @@ VoidPtr API_ROUTINE gds__alloc(SLONG size_request) } } - class InitPrefix { public: @@ -3818,6 +3818,55 @@ static bool GetProgramFilesDir(Firebird::PathName& output) } +// Plugin operations + +namespace { + Firebird::GlobalPtr pluginMutex; + Firebird::Plugin* pluginChain; +} // anonymous napespace + +void API_ROUTINE fb_register_plugin(Firebird::Plugin* plugin) +{ + // If initialization is complete, use mutex to protect pluginChain. + // Otherwise we are single-threaded, and have no need in such protection. + Firebird::Mutex* mutex(&pluginMutex); + if (mutex) + { + mutex->enter(); + } + + plugin->link(pluginChain); + pluginChain = plugin; + + if (mutex) + { + mutex->leave(); + } +} + +Firebird::Plugin* API_ROUTINE fb_query_plugin(unsigned int type, const char* name) +{ + Firebird::MutexLockGuard g(pluginMutex); + + Firebird::Plugin* prev = NULL; + for (Firebird::Plugin* p = pluginChain; p; prev = p, p = p->next()) + { + if (p->type() == type && ((!name) || (!strcmp(name, p->name())))) + { + if (prev) + prev->link(p->next()); + else + pluginChain = p->next(); + + p->link(NULL); + return p; + } + } + + return NULL; +} + + // Deprecated private API functions extern "C" diff --git a/src/jrd/idx.h b/src/jrd/idx.h index 3d7e18e3dd..83dfd63821 100644 --- a/src/jrd/idx.h +++ b/src/jrd/idx.h @@ -346,10 +346,6 @@ static const struct ini_idx_t indices[] = SEGMENT(f_prm_name, idx_metadata), // parameter name SEGMENT(f_prm_pkg_name, idx_metadata) // package name }}, - // define index RDB$INDEX_52 for RDB$USERS unique RDB$USER_NAME; - INDEX(52, ODS_12_0, rel_users, idx_unique, 1) - SEGMENT(f_user_name, idx_metadata) // procedure name - }} // Last index in ODS 12.0 is RDB$INDEX_51 }; diff --git a/src/jrd/ini.epp b/src/jrd/ini.epp index 15cfa986fc..c9ddecb974 100644 --- a/src/jrd/ini.epp +++ b/src/jrd/ini.epp @@ -472,35 +472,6 @@ void INI_format(const TEXT* owner, const TEXT* charset) add_security_to_sys_rel(tdbb, ownerName, "RDB$PAGES", buffer, length, true); // DFW writes here add_security_to_sys_rel(tdbb, ownerName, "RDB$FORMATS", buffer, length, true); - - // nobody except DBA should access it - acl = buffer; - *acl++ = ACL_version; - *acl++ = ACL_id_list; - *acl++ = id_person; - - length = ownerName.length(); - if (length > MAX_UCHAR) - length = MAX_UCHAR; - - *acl++ = (UCHAR)length; - if (length) - { - const TEXT* p_1 = ownerName.c_str(); - memcpy(acl, p_1, length); - acl += length; - } - *acl++ = ACL_end; - *acl++ = ACL_priv_list; - *acl++ = priv_protect; - *acl++ = priv_control; - *acl++ = priv_delete; - *acl++ = priv_write; - *acl++ = priv_read; - *acl++ = ACL_end; - *acl++ = ACL_end; - length = acl - buffer; - add_security_to_sys_rel(tdbb, ownerName, "RDB$USERS", buffer, length, false); } diff --git a/src/jrd/jrd_pwd.h b/src/jrd/jrd_pwd.h index c21b1b69a6..91d92de399 100644 --- a/src/jrd/jrd_pwd.h +++ b/src/jrd/jrd_pwd.h @@ -112,8 +112,6 @@ class SecurityDatabaseServer : public ServerPlugin { public: ServerInstance* instance(); - void getName(const char** data, unsigned short* dataSize); - void release(); }; class SecurityDatabaseServerInstance : public ServerInstance diff --git a/src/jrd/names.h b/src/jrd/names.h index 4c04c99c5f..c0b8bb6f37 100644 --- a/src/jrd/names.h +++ b/src/jrd/names.h @@ -257,17 +257,14 @@ NAME("RDB$ARGUMENT_MECHANISM", nam_arg_mechanism) NAME("RDB$ARGUMENT_NAME", nam_arg_name) NAME("RDB$IDENTITY_TYPE", nam_identity_type) -NAME("RDB$USERS", nam_users) -NAME("RDB$USER_NAME", nam_user_name) -NAME("RDB$GROUP_NAME", nam_group_name) -NAME("RDB$UID", nam_uid) -NAME("RDB$GID", nam_gid) -NAME("RDB$PASSWD_TYPE", nam_passwd_type) -NAME("RDB$PASSWD", nam_passwd) -NAME("RDB$FIRST_NAME", nam_first_name) -NAME("RDB$MIDDLE_NAME", nam_middle_name) -NAME("RDB$LAST_NAME", nam_last_name) -NAME("RDB$NAME_PART", nam_name_part) +NAME("SEC$USER_NAME", nam_user_name) +NAME("SEC$GROUP_NAME", nam_group_name) +NAME("SEC$UID", nam_uid) +NAME("SEC$GID", nam_gid) +NAME("SEC$FIRST_NAME", nam_first_name) +NAME("SEC$MIDDLE_NAME", nam_middle_name) +NAME("SEC$LAST_NAME", nam_last_name) +NAME("SEC$NAME_PART", nam_name_part) NAME("MON$ATTACHMENTS", nam_mon_attachments) NAME("MON$ATTACHMENT_ID", nam_mon_att_id) diff --git a/src/jrd/os/posix/mod_loader.cpp b/src/jrd/os/posix/mod_loader.cpp index bc4fb4ed99..15d8c01716 100644 --- a/src/jrd/os/posix/mod_loader.cpp +++ b/src/jrd/os/posix/mod_loader.cpp @@ -85,7 +85,12 @@ ModuleLoader::Module *ModuleLoader::loadModule(const Firebird::PathName& modPath { void* module = dlopen(modPath.nullStr(), RTLD_LAZY); if (module == NULL) + { +#ifdef DEV_BUILD + gds__log("loadModule failed loading %s: %s", modPath.c_str(), dlerror()); +#endif return 0; + } return FB_NEW(*getDefaultMemoryPool()) DlfcnModule(module); } diff --git a/src/jrd/pwd.cpp b/src/jrd/pwd.cpp index 2b2ccd59be..bd39fc0ac0 100644 --- a/src/jrd/pwd.cpp +++ b/src/jrd/pwd.cpp @@ -41,11 +41,17 @@ #include "../common/config/config.h" #include "../common/classes/objects_array.h" #include "../common/classes/init.h" +#include "../common/classes/ImplementHelper.h" using namespace Firebird; namespace { +// register plugin + +char name[] = "LEGACY_AUTH"; +PluginHelper server; + // temporal implementation of timer GlobalPtr timerMutex; @@ -138,27 +144,27 @@ const UCHAR PWD_REQUEST[] = blr_begin, blr_for, blr_rse, 1, - blr_relation, 9, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', 'S', 0, + blr_relation, 9, 'P', 'L', 'G', '$', 'U', 'S', 'E', 'R', 'S', 0, blr_first, blr_literal, blr_short, 0, 1, 0, blr_boolean, blr_eql, - blr_field, 0, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'N', 'A', 'M', 'E', + blr_field, 0, 13, 'P', 'L', 'G', '$', 'U', 'S', 'E', 'R', '_', 'N', 'A', 'M', 'E', blr_parameter, 0, 0, 0, blr_end, blr_send, 1, blr_begin, blr_assignment, - blr_field, 0, 7, 'R', 'D', 'B', '$', 'G', 'I', 'D', + blr_field, 0, 7, 'P', 'L', 'G', '$', 'G', 'I', 'D', blr_parameter, 1, 0, 0, blr_assignment, - blr_field, 0, 7, 'R', 'D', 'B', '$', 'U', 'I', 'D', + blr_field, 0, 7, 'P', 'L', 'G', '$', 'U', 'I', 'D', blr_parameter, 1, 1, 0, blr_assignment, blr_literal, blr_short, 0, 1, 0, blr_parameter, 1, 2, 0, blr_assignment, - blr_field, 0, 10, 'R', 'D', 'B', '$', 'P', 'A', 'S', 'S', 'W', 'D', + blr_field, 0, 10, 'P', 'L', 'G', '$', 'P', 'A', 'S', 'S', 'W', 'D', blr_parameter, 1, 3, 0, blr_end, blr_send, 1, @@ -433,19 +439,7 @@ void SecurityDatabase::shutdown(void*) ServerInstance* SecurityDatabaseServer::instance() { - return interfaceAlloc(); -} - -void SecurityDatabaseServer::getName(const char** data, unsigned short* dataSize) -{ - static char name[] = "LEGACY_AUTH"; - *data = name; - *dataSize = strlen(name); -} - -void SecurityDatabaseServer::release() -{ - gds__free(this); + return Firebird::interfaceAlloc(); } Result SecurityDatabaseServerInstance::startAuthentication(bool isService, const char*, @@ -470,7 +464,7 @@ void SecurityDatabaseServerInstance::getData(const unsigned char** data, unsigne void SecurityDatabaseServerInstance::release() { - gds__free(this); + interfaceFree(this); } } // namespace Auth diff --git a/src/jrd/relations.h b/src/jrd/relations.h index 0f0cfb61e0..82e752f7dc 100644 --- a/src/jrd/relations.h +++ b/src/jrd/relations.h @@ -591,21 +591,7 @@ RELATION(nam_packages, rel_packages, ODS_12_0, rel_persistent) FIELD(f_pkg_desc, nam_description, fld_description, 1, ODS_12_0) END_RELATION -// Relation 43 (RDB$USERS) -RELATION(nam_users, rel_users, ODS_12_0, rel_persistent) - FIELD(f_user_name, nam_user_name, fld_user, 1, ODS_12_0) - FIELD(f_group_name, nam_group_name, fld_user, 1, ODS_12_0) - FIELD(f_uid, nam_uid, fld_uid, 1, ODS_12_0) - FIELD(f_gid, nam_gid, fld_gid, 1, ODS_12_0) - FIELD(f_passwd_type, nam_passwd_type, fld_passwd_type, 1, ODS_12_0) - FIELD(f_passwd, nam_passwd, fld_passwd, 1, ODS_12_0) - FIELD(f_first_name, nam_first_name, fld_name_part, 1, ODS_12_0) - FIELD(f_middle_name, nam_middle_name, fld_name_part, 1, ODS_12_0) - FIELD(f_last_name, nam_last_name, fld_name_part, 1, ODS_12_0) - FIELD(f_user_desc, nam_description, fld_description, 1, ODS_12_0) -END_RELATION - -// Relation 44 (SEC$USERS) +// Relation 43 (SEC$USERS) RELATION(nam_sec_users, rel_sec_users, ODS_12_0, rel_virtual) FIELD(f_sec_user_name, nam_user_name, fld_user, 1, ODS_12_0) FIELD(f_sec_group_name, nam_group_name, fld_user, 1, ODS_12_0) diff --git a/src/misc/smallog.cpp b/src/misc/smallog.cpp new file mode 100644 index 0000000000..b4d7ee3b39 --- /dev/null +++ b/src/misc/smallog.cpp @@ -0,0 +1,121 @@ +/* + * PROGRAM: Prepare svn's log output to become our ChangeLog + * MODULE: smallog.cpp + * DESCRIPTION: Removes unneeded data from input file. + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alexander Peshkoff + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2010 Alexander Peshkoff + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include +#include + +#define CH_PATHS "Changed paths:" +#define IBN "increment build number" +#define NU "nightly update" + +#define TRUNK "/firebird/trunk/" +#define BRANCHES "/firebird/branches/" +#define TAGS "/firebird/tags/" + +int main(int ac, char** av) +{ + char s[32 * 1024]; + long retPos = -1; + bool firstLine = false; + bool skipped = true; + const char* master = av[1] ? av[1] : TRUNK; + char buf[1024]; + const char* branch = NULL; + if (av[1]) + { + sprintf(buf, "A %s (from", av[1]); + branch = buf; + } + + while (gets(s)) + { + if (firstLine) + { + // r51338 | dimitr | 2010-07-13 16:32:36 +0400 (Tue, 13 Jul 2010) | 1 line + char* rev = strtok(s, "|"); + char* nam = strtok(NULL, "|"); + char* dat = strtok(NULL, "|"); + char* colon = dat ? strrchr(dat, ':') : NULL; + if (colon) + *colon = '\0'; + printf("%s %s\n", dat, nam); + firstLine = false; + continue; + } + if (!strncmp(s, "----", 4)) + { + // new item + if (!skipped) + puts(""); + firstLine = true; + skipped = false; + retPos = ftell(stdout); + continue; + } + + if ((!strcmp(s, IBN)) || (!strcmp(s, NU))) + { + if (fseek(stdout, retPos, SEEK_SET) < 0) + { + perror("fseek"); + return 1; + } + skipped = true; + continue; + } + if (skipped) + continue; + if (!strcmp(s, CH_PATHS)) + continue; + + char* trunk = strstr(s, master); + if (branch && strstr(s, branch)) + { + // branch was created here + branch = NULL; + master = TRUNK; + } + else if (trunk) + { + int l = strlen(trunk + strlen(master)); + memmove(trunk, trunk + strlen(master), l + 1); + } + else + { + if (strstr(s, TAGS)) + continue; + if (strstr(s, BRANCHES)) + continue; + if (strstr(s, TRUNK)) + continue; + } + + if (strlen(s)) + puts(s); + } + + return 0; +} diff --git a/src/plugins/udr_engine/UdrEngine.cpp b/src/plugins/udr_engine/UdrEngine.cpp index 1429cb6861..cdb27c5e78 100644 --- a/src/plugins/udr_engine/UdrEngine.cpp +++ b/src/plugins/udr_engine/UdrEngine.cpp @@ -764,7 +764,7 @@ public: } factory; -extern "C" void FB_PLUGIN_ENTRY_POINT(Error* error, Plugin* plugin) +extern "C" void FB_PLUGIN_ENTRY_POINT(Error* error, ExtEngPlugin* plugin) { if (plugin->getLibraryName()) libraryName->assign(plugin->getLibraryName()); diff --git a/src/remote/interface.cpp b/src/remote/interface.cpp index 41a5813625..e57697dfcb 100644 --- a/src/remote/interface.cpp +++ b/src/remote/interface.cpp @@ -64,8 +64,9 @@ #include "../common/utils_proto.h" #include "../common/classes/DbImplementation.h" #include "../auth/Auth.h" -#include "../auth/SecurityDatabase/LegacyClient.h" -#include "../auth/trusted/AuthSspi.h" +//#include "../auth/SecurityDatabase/LegacyClient.h" +//#include "../auth/trusted/AuthSspi.h" +#include "../common/classes/ImplementHelper.h" #ifdef HAVE_UNISTD_H #include @@ -5695,15 +5696,11 @@ namespace explicit InitList(MemoryPool& p) : HalfStaticArray(p) { - // this code will be replaced with known plugins scan - push(interfaceAlloc()); -#ifdef TRUSTED_AUTH - push(interfaceAlloc()); -#endif -#ifdef AUTH_DEBUG - push(interfaceAlloc()); -#endif - + Firebird::Plugin* plugin; + while ( (plugin = fb_query_plugin(Firebird::Plugin::AuthClient, NULL)) ) + { + push(reinterpret_cast(plugin)); + } // must be last push(NULL); } @@ -5739,7 +5736,6 @@ static bool init(ISC_STATUS* user_status, // current instance name const char* nm; - USHORT len; // Let plugins try to add data to DPB in order to avoid extra network roundtrip AutoPtr currentInstance; @@ -5754,7 +5750,7 @@ static bool init(ISC_STATUS* user_status, { // plugin may be used currentInstance.reset(list[sequence]->instance()); - list[sequence]->getName(&nm, &len); + nm = list[sequence]->name(); switch(currentInstance->startAuthentication(op == op_service_attach, file_name.c_str(), &di)) { @@ -5861,7 +5857,7 @@ static bool init(ISC_STATUS* user_status, if (n && n->cstr_length && currentInstance.hasData()) { // if names match, do not reset instance - if (len == n->cstr_length && memcmp(nm, n->cstr_address, len) == 0) + if (strlen(nm) == n->cstr_length && memcmp(nm, n->cstr_address, n->cstr_length) == 0) { n = NULL; } @@ -5874,8 +5870,8 @@ static bool init(ISC_STATUS* user_status, for (sequence = 0; list[sequence]; ++sequence) { - list[sequence]->getName(&nm, &len); - if (len == n->cstr_length && memcmp(nm, n->cstr_address, len) == 0) + nm = list[sequence]->name(); + if (strlen(nm) == n->cstr_length && memcmp(nm, n->cstr_address, n->cstr_length) == 0) { currentInstance.reset(list[sequence]->instance()); break; @@ -5905,7 +5901,7 @@ static bool init(ISC_STATUS* user_status, if (contFlag) { // continue auth - if (!currentInstance) + if (!currentInstance.hasData()) { break; } @@ -5915,6 +5911,11 @@ static bool init(ISC_STATUS* user_status, } } + + if (!currentInstance.hasData()) + { + break; + } // send answer (may be empty) to server packet->p_operation = op_trusted_auth; d = &packet->p_trau.p_trau_data; diff --git a/src/remote/server.cpp b/src/remote/server.cpp index dcd6e90762..d2db479bf2 100644 --- a/src/remote/server.cpp +++ b/src/remote/server.cpp @@ -69,8 +69,9 @@ #include "../remote/proto_proto.h" // xdr_protocol_overhead() #include "../common/classes/DbImplementation.h" #include "../auth/Auth.h" -#include "../jrd/jrd_pwd.h" -#include "../auth/trusted/AuthSspi.h" +//#include "../jrd/jrd_pwd.h" +//#include "../auth/trusted/AuthSspi.h" +#include "../common/classes/ImplementHelper.h" using namespace Firebird; @@ -222,22 +223,11 @@ public: explicit InitList(MemoryPool& p) : HalfStaticArray(p) { - PathName authMethod(Config::getAuthMethod()); - - // this code will be replaced with known plugins scan - if (authMethod == AmNative || authMethod == AmMixed) + Firebird::Plugin* plugin; + while ( (plugin = fb_query_plugin(Firebird::Plugin::AuthServer, NULL)) ) { - push(interfaceAlloc()); + push(reinterpret_cast(plugin)); } -#ifdef TRUSTED_AUTH - if (authMethod == AmTrusted || authMethod == AmMixed) - { - push(interfaceAlloc()); - } -#endif -#ifdef AUTH_DEBUG - push(interfaceAlloc()); -#endif // must be last push(NULL); @@ -342,7 +332,8 @@ public: if (first) { // violate constness here safely - send operation does not modify data - list[sequence]->getName((const char**)(&s->cstr_address), &s->cstr_length); + s->cstr_address = (UCHAR*) list[sequence]->name(); + s->cstr_length = strlen(list[sequence]->name()); } else { diff --git a/src/utilities/gsec/security.cpp b/src/utilities/gsec/security.cpp new file mode 100644 index 0000000000..3db969a31f --- /dev/null +++ b/src/utilities/gsec/security.cpp @@ -0,0 +1,117 @@ +/* + * + * PROGRAM: Security data base manager + * MODULE: security.cpp + * DESCRIPTION: Security routines + * + * The contents of this file are subject to the Interbase Public + * License Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy + * of the License at http://www.Inprise.com/IPL.html + * + * Software distributed under the License is distributed on an + * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express + * or implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code was created by Inprise Corporation + * and its predecessors. Portions created by Inprise Corporation are + * Copyright (C) Inprise Corporation. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + * Alex Peshkoff + */ + +#include "firebird.h" +#include +#include +#include +#include +#include "../jrd/common.h" +#include "../jrd/ibase.h" +#include "../jrd/jrd_pwd.h" +#include "../jrd/enc_proto.h" +#include "../jrd/gds_proto.h" +#include "../jrd/isc_proto.h" +#include "../jrd/os/mod_loader.h" +#include "../utilities/gsec/gsec.h" +#include "../utilities/gsec/secur_proto.h" +#include "../common/utils_proto.h" +#include "../common/classes/init.h" +#include "../common/classes/UserBlob.h" +#include "../common/classes/Interface.h" +#include "../common/utils_proto.h" + +using namespace Firebird; + +SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, + const char *realUser, + FB_API_HANDLE db, + FB_API_HANDLE trans, + internal_user_data* io_user_data, + FPTR_SECURITY_CALLBACK display_func, + void* callback_arg) +{ + static Auth::ManagementPlugin* volatile plugin = NULL; + if (!plugin) + { + static GlobalPtr mutex; + MutexLockGuard g(mutex); + if (!plugin) + { + // temporary measure before PluginManager integration + Firebird::PathName plugFile(fb_utils::getPrefix(fb_utils::FB_DIR_PLUGINS, "user_management")); + ModuleLoader::doctorModuleExtension(plugFile); + ModuleLoader::loadModule(plugFile); + + plugin = reinterpret_cast + (fb_query_plugin(Firebird::Plugin::UserManagement, NULL)); + } + if (!plugin) + { + (Arg::Gds(isc_random) << "Missing user management plugin").copyTo(isc_status); + return GsecMsg75; + } + } + + return plugin->execLine(isc_status, realUser, db, trans, io_user_data, display_func, callback_arg); +} + +SSHORT SECURITY_exec_line(ISC_STATUS* isc_status, + const char *realUser, + FB_API_HANDLE db, + internal_user_data* io_user_data, + FPTR_SECURITY_CALLBACK display_func, + void* callback_arg) +{ + FB_API_HANDLE tra = 0; + + if (isc_start_transaction(isc_status, &tra, 1, &db, 0, NULL)) + { + return GsecMsg75; // gsec error + } + + SSHORT ret = SECURITY_exec_line(isc_status, realUser, db, tra, io_user_data, display_func, callback_arg); + + // rollback if we have an error using tmp_status to avoid + // overwriting the error status which the caller wants to see + + ISC_STATUS_ARRAY tmp_status; + + if (ret) + { + isc_rollback_transaction(tmp_status, &tra); + } + else + { + if (isc_commit_transaction(isc_status, &tra)) + { + // CVC: Shouldn't we call isc_rollback_transaction() here? + isc_rollback_transaction(tmp_status, &tra); + return GsecMsg75; // gsec error + } + } + + return ret; +}