mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 09:20:39 +01:00
Moved authentication code from engine to remote listener.
Get ready for authentication plugins.
This commit is contained in:
parent
a71aca4c23
commit
55e717f810
@ -40,7 +40,7 @@ include $(ROOT)/gen/make.shared.variables
|
||||
@SET_MAKE@
|
||||
|
||||
SERVER_Files = $(OS_ServerFiles) server.cpp server_stub.cpp
|
||||
SERVER_Sources = $(addprefix remote/, $(SERVER_Files))
|
||||
SERVER_Sources = $(addprefix remote/, $(SERVER_Files)) jrd/pwd.cpp
|
||||
SERVER_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(SERVER_Sources)))) $(LIBFBSERVER_Objects) $(COMMON_Objects)
|
||||
|
||||
.PHONY: fbserver
|
||||
|
@ -47,8 +47,8 @@ unexport ISC_USER
|
||||
unexport ISC_PASSWORD
|
||||
|
||||
|
||||
SERVER_Files = $(OS_ServerFiles) server.cpp
|
||||
SERVER_Sources = $(addprefix remote/, $(SERVER_Files))
|
||||
SERVER_Files = $(OS_ServerFiles) server.cpp
|
||||
SERVER_Sources = $(addprefix remote/, $(SERVER_Files)) jrd/pwd.cpp
|
||||
SERVER_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(SERVER_Sources))))
|
||||
|
||||
|
||||
|
@ -42,7 +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_stub.cpp
|
||||
SERVER_Other_sources = common/cvt.cpp common/classes/DbImplementation.cpp
|
||||
SERVER_Other_sources = common/cvt.cpp common/classes/DbImplementation.cpp \
|
||||
jrd/pwd.cpp jrd/sha.cpp jrd/guid.cpp auth/Auth.cpp
|
||||
SERVER_Sources = $(addprefix remote/, $(SERVER_Files)) $(addprefix jrd/, $(SERVER_JrdFiles)) $(SERVER_Other_sources)
|
||||
|
||||
REMOTE_CommonSources = $(addprefix remote/, $(REMOTE_CommonFiles))
|
||||
|
@ -19,7 +19,7 @@
|
||||
# Use SOLX86 to identify x86 version of Solaris. Neil McCalden
|
||||
# 2 Oct 2002, Nickolay Samofatov - Major Cleanup
|
||||
|
||||
WARNINGS=-Wall -W -Wno-unused -Wno-parentheses -Wno-switch -Wwrite-strings
|
||||
WARNINGS=-Wall -W -Wno-unused -Wno-parentheses -Wno-switch -Wwrite-strings -Wno-non-virtual-dtor
|
||||
COMM_SOLX_FLAGS:=-DSOLARIS -DBSD_COMP -fno-omit-frame-pointer -fmessage-length=0 -MMD -fPIC
|
||||
|
||||
SFIO=@SFIO_DIR@
|
||||
|
@ -36,7 +36,7 @@ JRD_ServerFiles= blob_filter.cpp cvt.cpp dpm.epp dyn.epp dyn_def.epp \
|
||||
IntlUtil.cpp isc_sync.cpp \
|
||||
jrd.cpp Attachment.cpp Database.cpp lck.cpp \
|
||||
mov.cpp opt.cpp Optimizer.cpp pag.cpp par.cpp \
|
||||
ods.cpp PluginManager.cpp pwd.cpp PreparedStatement.cpp RandomGenerator.cpp \
|
||||
ods.cpp PluginManager.cpp PreparedStatement.cpp RandomGenerator.cpp \
|
||||
Relation.cpp ResultSet.cpp rlck.cpp rpb_chain.cpp \
|
||||
sdw.cpp shut.cpp sort.cpp sqz.cpp \
|
||||
svc.cpp SysFunction.cpp TempSpace.cpp tpc.cpp tra.cpp validation.cpp \
|
||||
@ -108,12 +108,13 @@ LOCK_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(LOCK_Sources)))
|
||||
REMOTE_CommonFiles = inet.cpp merge.cpp \
|
||||
parser.cpp protocol.cpp remote.cpp xdr.cpp
|
||||
|
||||
REMOTE_ClientFiles = interface.cpp
|
||||
REMOTE_ClientFiles = interface.cpp
|
||||
|
||||
INTERFACE_Files= $(REMOTE_ClientFiles) $(REMOTE_CommonFiles)
|
||||
|
||||
|
||||
INTERFACE_Sources = $(addprefix remote/, $(INTERFACE_Files))
|
||||
INTERFACE_Sources = $(addprefix remote/, $(INTERFACE_Files)) \
|
||||
auth/Auth.cpp auth/SecurityDatabase/LegacyClient.cpp
|
||||
INTERFACE_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(INTERFACE_Sources))))
|
||||
|
||||
ifeq ($(PLATFORM),win32)
|
||||
|
@ -63,7 +63,7 @@ SHRLIB_FOREIGN_EXT=a
|
||||
PROD_FLAGS=-ggdb -O3 -fsigned-char -fmessage-length=0 -fno-omit-frame-pointer -pipe -MMD -fPIC
|
||||
|
||||
# -Wno-unused-variable
|
||||
DEV_FLAGS=-ggdb -O0 -fsigned-char -fmessage-length=0 -pipe -MMD -fPIC -Wall -Wextra -Wno-unused-parameter -Wno-switch -Wno-parentheses -Wno-unknown-pragmas
|
||||
DEV_FLAGS=-ggdb -O0 -fsigned-char -fmessage-length=0 -pipe -MMD -fPIC -Wall -Wextra -Wno-unused-parameter -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-non-virtual-dtor
|
||||
|
||||
# link options when using IBM /usr/bin/ld fronted by g++
|
||||
LINK_OPTS= $(LDFLAGS) $(THR_FLAGS) $(UNDEF_FLAGS) $(LIB_PATH_OPTS) -Wl,-bbigtoc,-brtl
|
||||
|
@ -33,7 +33,7 @@ export MACOSX_DEPLOYMENT_TARGET
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
||||
PROD_FLAGS=-O3 -DDARWIN -pipe -p -MMD -fPIC -fno-common -arch i386 -mmacosx-version-min=10.4
|
||||
DEV_FLAGS=-ggdb -DDARWIN -pipe -p -MMD -fPIC -fno-common -Wall -arch i386 -mmacosx-version-min=10.4
|
||||
DEV_FLAGS=-ggdb -DDARWIN -pipe -p -MMD -fPIC -fno-common -Wall -arch i386 -mmacosx-version-min=10.4 -Wno-non-virtual-dtor
|
||||
CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -fno-weak
|
||||
EMBED_UTIL_TARGETS=gstat gds_drop gds_relay gsec fbguard nbackup fb_lock_print fbsvcmgr fbtracemgr
|
||||
CLIENT_UTIL_TARGETS=gds_drop gds_relay gstat gsec fbguard fbmgr_bin nbackup fb_lock_print fbsvcmgr \
|
||||
|
@ -26,7 +26,7 @@ export MACOSX_DEPLOYMENT_TARGET
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
||||
PROD_FLAGS=-DDARWIN -pipe -p -MMD -fPIC -fno-common -arch ppc -mmacosx-version-min=10.2
|
||||
DEV_FLAGS=-ggdb -DDARWIN -pipe -p -MMD -fPIC -fno-common -Wall -arch ppc -mmacosx-version-min=10.2
|
||||
DEV_FLAGS=-ggdb -DDARWIN -pipe -p -MMD -fPIC -fno-common -Wall -arch ppc -mmacosx-version-min=10.2 -Wno-non-virtual-dtor
|
||||
CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -fno-weak
|
||||
EMBED_UTIL_TARGETS=gstat gds_relay gsec fbguard nbackup fb_lock_print fbsvcmgr fbtracemgr
|
||||
CLIENT_UTIL_TARGETS=gds_relay gstat gsec fbguard fbmgr_bin nbackup fb_lock_print fbsvcmgr fbtracemgr
|
||||
|
@ -38,7 +38,7 @@ export MACOSX_DEPLOYMENT_TARGET
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
||||
PROD_FLAGS=-O3 -DDARWIN -pipe -p -MMD -fPIC -fno-common -mmacosx-version-min=10.5
|
||||
DEV_FLAGS=-ggdb -DDARWIN -pipe -p -MMD -fPIC -fno-common -Wall -mmacosx-version-min=10.5
|
||||
DEV_FLAGS=-ggdb -DDARWIN -pipe -p -MMD -fPIC -fno-common -Wall -mmacosx-version-min=10.5 -Wno-non-virtual-dtor
|
||||
CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden
|
||||
EMBED_UTIL_TARGETS=gstat gds_drop gds_relay gsec nbackup fb_lock_print fbsvcmgr fbtracemgr
|
||||
CLIENT_UTIL_TARGETS=gds_drop gds_relay gstat gsec fbguard fbmgr_bin nbackup fb_lock_print fbsvcmgr \
|
||||
|
@ -28,7 +28,7 @@ export MACOSX_DEPLOYMENT_TARGET
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
||||
PROD_FLAGS=-O3 -DDARWIN -pipe -p -MMD -fPIC -fno-common -mmacosx-version-min=10.5
|
||||
DEV_FLAGS=-ggdb -DDARWIN -pipe -p -MMD -fPIC -fno-common -Wall -mmacosx-version-min=10.5
|
||||
DEV_FLAGS=-ggdb -DDARWIN -pipe -p -MMD -fPIC -fno-common -Wall -mmacosx-version-min=10.5 -Wno-non-virtual-dtor
|
||||
CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -fno-weak
|
||||
EMBED_UTIL_TARGETS=gstat gds_drop gds_relay gsec fbguard nbackup fb_lock_print fbsvcmgr fbtracemgr
|
||||
CLIENT_UTIL_TARGETS=gds_drop gds_relay gstat gsec fbguard fbmgr_bin nbackup fb_lock_print fbsvcmgr \
|
||||
|
@ -23,7 +23,7 @@ OS_ServerFiles=inet_server.cpp
|
||||
LINK_OPTS+=-Wl,-rpath,../gen/firebird/lib
|
||||
|
||||
PROD_FLAGS=-O -fno-builtin -DFREEBSD -pipe -MMD -fPIC
|
||||
DEV_FLAGS=-ggdb -DFREEBSD -pipe -MMD -p -fPIC -Wall
|
||||
DEV_FLAGS=-ggdb -DFREEBSD -pipe -MMD -p -fPIC -Wall -Wno-non-virtual-dtor
|
||||
EMBED_UTIL_TARGETS=gstat gsec nbackup fbguard fb_lock_print
|
||||
CLIENT_UTIL_TARGETS=gstat gsec fbguard fbmgr_bin nbackup fb_lock_print
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -pipe -MMD -fPIC -fmessage-length=0
|
||||
OPTIMIZE_FLAGS=-O3 -march=i586 -mtune=i686 -fno-omit-frame-pointer
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-non-virtual-dtor
|
||||
|
||||
PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
|
||||
#DEV_FLAGS=-DUSE_VALGRIND -p $(COMMON_FLAGS) $(WARN_FLAGS)
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DAMD64 -pipe -MMD -fPIC -fmessage-length=0
|
||||
OPTIMIZE_FLAGS=-O3 -fno-omit-frame-pointer
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-invalid-offsetof
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-invalid-offsetof -Wno-non-virtual-dtor
|
||||
CXXFLAGS:= $(CXXFLAGS) -fno-rtti
|
||||
|
||||
PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
|
||||
|
@ -24,7 +24,7 @@
|
||||
#DEV_FLAGS=-ggdb -DLINUX -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch
|
||||
|
||||
PROD_FLAGS=-O3 -DLINUX -DARM -pipe -p -MMD -fPIC -fsigned-char -fmessage-length=0
|
||||
DEV_FLAGS=-ggdb -DLINUX -DARM -pipe -p -MMD -fPIC -Wall -fsigned-char -fmessage-length=0
|
||||
DEV_FLAGS=-ggdb -DLINUX -DARM -pipe -p -MMD -fPIC -Wall -fsigned-char -fmessage-length=0 -Wno-non-virtual-dtor
|
||||
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
COMMON_FLAGS=-DLINUX -pipe -MMD -fPIC -DFB_SEND_FLAGS=MSG_NOSIGNAL
|
||||
|
||||
PROD_FLAGS=-ggdb -O3 $(COMMON_FLAGS)
|
||||
DEV_FLAGS=-ggdb -p -Wall -Wno-switch $(COMMON_FLAGS)
|
||||
DEV_FLAGS=-ggdb -p -Wall -Wno-switch $(COMMON_FLAGS) -Wno-non-virtual-dtor
|
||||
CXXFLAGS:= $(CXXFLAGS) -fno-rtti
|
||||
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DIA64 -pipe -MMD -fPIC -fmessage-length=0
|
||||
OPTIMIZE_FLAGS=-O3 -fno-omit-frame-pointer
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-non-virtual-dtor
|
||||
CXXFLAGS:= $(CXXFLAGS) -fno-rtti
|
||||
|
||||
PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
|
||||
|
@ -1,6 +1,6 @@
|
||||
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -pipe -MMD -fPIC -fmessage-length=0
|
||||
OPTIMIZE_FLAGS=-O3 -fno-omit-frame-pointer -fno-builtin
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-non-virtual-dtor
|
||||
|
||||
PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
|
||||
#DEV_FLAGS=-DUSE_VALGRIND -p $(COMMON_FLAGS) $(WARN_FLAGS)
|
||||
|
@ -22,7 +22,7 @@ LD=@CXX@
|
||||
# -fno-builtin is used because GCC 3.0-3.2.2 had bug with builtins expansion
|
||||
# you may remove it if engine is getting compiled with any other GCC version
|
||||
PROD_FLAGS=-ggdb -O3 -fno-omit-frame-pointer -DLINUX -pipe -MMD -fPIC
|
||||
DEV_FLAGS=-ggdb -DLINUX -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch
|
||||
DEV_FLAGS=-ggdb -DLINUX -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch -Wno-non-virtual-dtor
|
||||
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
||||
|
@ -19,8 +19,8 @@
|
||||
# 2 Oct 2002, Nickolay Samofatov - Major cleanup
|
||||
|
||||
PROD_FLAGS=-ggdb -fno-omit-frame-pointer -fsigned-char -DLINUX -pipe -MMD -fPIC -fmessage-length=0 -DLINUX -DPowerPC -DPPC -O3 -mcpu=powerpc
|
||||
DEV_FLAGS=-ggdb -O0 -DLINUX -pipe -MMD -p -fPIC -Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -fmessage-length=0 -fsigned-char -DLINUX -DPowerPC -DPPC
|
||||
#DEV_FLAGS=-DUSE_VALGRIND -ggdb -O0 -DLINUX -pipe -MMD -p -fPIC -Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -fmessage-length=0 -DLINUX -DPowerPC -DPPC
|
||||
DEV_FLAGS=-ggdb -O0 -DLINUX -pipe -MMD -p -fPIC -Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -fmessage-length=0 -fsigned-char -DLINUX -DPowerPC -DPPC -Wno-non-virtual-dtor
|
||||
#DEV_FLAGS=-DUSE_VALGRIND -ggdb -O0 -DLINUX -pipe -MMD -p -fPIC -Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -fmessage-length=0 -DLINUX -DPowerPC -DPPC -Wno-non-virtual-dtor
|
||||
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -pipe -MMD -fPIC -fmessage-length=0 -fsigned-char
|
||||
OPTIMIZE_FLAGS=-O3 -fno-omit-frame-pointer -fno-builtin
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-non-virtual-dtor
|
||||
|
||||
PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
|
||||
DEV_FLAGS=-DUSE_VALGRIND -p $(COMMON_FLAGS) $(WARN_FLAGS)
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
COMMON_FLAGS=-m32 -DLINUX -pipe -MMD -fPIC -Dsparc -DFB_SEND_FLAGS=MSG_NOSIGNAL
|
||||
PROD_FLAGS=-ggdb -mcpu=ultrasparc -mtune=ultrasparc -O3 $(COMMON_FLAGS)
|
||||
DEV_FLAGS=-ggdb -p -Wall -Wno-switch $(COMMON_FLAGS)
|
||||
DEV_FLAGS=-ggdb -p -Wall -Wno-switch $(COMMON_FLAGS) -Wno-non-virtual-dtor
|
||||
CXXFLAGS:= $(CXXFLAGS) -fno-rtti
|
||||
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
|
@ -20,8 +20,8 @@
|
||||
#
|
||||
|
||||
# -Wno-unused-variable is used due to unused gpre generated variables
|
||||
PROD_FLAGS=-O2 -march=i586 -DMINGW -mno-cygwin -Wall -Wshadow -Wundef -Wno-long-long -Wno-unused-variable -Wno-sign-compare -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD -mthreads
|
||||
DEV_FLAGS=-ggdb -march=i586 -DMINGW -mno-cygwin -Wall -Wshadow -Wundef -Wno-long-long -Wno-unused-variable -Wno-sign-compare -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD -mthreads
|
||||
PROD_FLAGS=-O2 -march=i586 -DMINGW -mno-cygwin -Wall -Wshadow -Wundef -Wno-long-long -Wno-unused-variable -Wno-sign-compare -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD -mthreads -Wno-non-virtual-dtor
|
||||
DEV_FLAGS=-ggdb -march=i586 -DMINGW -mno-cygwin -Wall -Wshadow -Wundef -Wno-long-long -Wno-unused-variable -Wno-sign-compare -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD -mthreads -Wno-non-virtual-dtor
|
||||
|
||||
PLATFORM_PATH=os/win32
|
||||
|
||||
|
@ -23,7 +23,7 @@ OS_ServerFiles=inet_server.cpp
|
||||
LINK_OPTS=-Wl,--rpath -Wl,@prefix@/lib
|
||||
|
||||
PROD_FLAGS=-O -fno-builtin -pipe -MMD -fPIC
|
||||
DEV_FLAGS=-g -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch -Wno-parentheses
|
||||
DEV_FLAGS=-g -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch -Wno-parentheses -Wno-non-virtual-dtor
|
||||
|
||||
LIB_LINK_OPTIONS= -shared
|
||||
LIB_PLATFORM_RPATH= -Wl,--rpath -Wl,$(1)
|
||||
|
@ -17,7 +17,7 @@ CFLAGS_COMMON= -DSOLARIS -DBSD_COMP -Dsparc
|
||||
|
||||
# compile flags for GCC compiler
|
||||
COMMON_GCC_FLAGS= -MMD -fPIC -m64 -D__sparcv9 -mptr64 -mstack-bias -mno-v8plus -mcpu=v9
|
||||
DEBUG_GCC_FLAGS= -gstabs+ -g3 -Wall -Wno-switch -Wcast-align
|
||||
DEBUG_GCC_FLAGS= -gstabs+ -g3 -Wall -Wno-switch -Wcast-align -Wno-non-virtual-dtor
|
||||
#switch to dbx accoding SF gdb 64 bits mailfunction
|
||||
|
||||
PROD_GCC_FLAGS= -mcpu=ultrasparc -mtune=ultrasparc -O3
|
||||
|
@ -21,7 +21,7 @@
|
||||
#
|
||||
# Start of file prefix.solaris X 86 : $(VERSION) $(PLATFORM)
|
||||
|
||||
WARNINGS=-Wall -W -Wno-unused -Wno-parentheses -Wno-switch -Wwrite-strings
|
||||
WARNINGS=-Wall -W -Wno-unused -Wno-parentheses -Wno-switch -Wwrite-strings -Wno-non-virtual-dtor
|
||||
COMM_SOLX_FLAGS:=-DSOLARIS -DSOLX86 -DBSD_COMP -fno-omit-frame-pointer -fmessage-length=0 -MMD -fPIC
|
||||
|
||||
SFIO=@SFIO_DIR@
|
||||
|
@ -29,7 +29,7 @@
|
||||
# make sure that make.defaults uses -lncurses instead of -lcurses for
|
||||
# LINK_LIBS and STATICLINK_LIBS e.g. -lncurses -leditline
|
||||
|
||||
WARNINGS=-Wall -Wno-switch -Wno-parentheses -Wno-unused-variable
|
||||
WARNINGS=-Wall -Wno-switch -Wno-parentheses -Wno-unused-variable -Wno-non-virtual-dtor
|
||||
COMM_SOLX_FLAGS:=-DSOLARIS -DBSD_COMP -DAMD64 -pipe -fmessage-length=0 -MMD -fPIC
|
||||
|
||||
SFIO=@SFIO_DIR@
|
||||
|
@ -1026,6 +1026,7 @@ dnl # by module name
|
||||
|
||||
mkdir -p temp/boot/alice
|
||||
mkdir -p temp/boot/auth/trusted
|
||||
mkdir -p temp/boot/auth/SecurityDatabase
|
||||
mkdir -p temp/boot/burp
|
||||
mkdir -p temp/boot/common/classes
|
||||
mkdir -p temp/boot/common/config
|
||||
@ -1070,6 +1071,7 @@ mkdir -p temp/boot/vulcan
|
||||
mkdir -p temp/extern/binreloc
|
||||
mkdir -p temp/std/alice
|
||||
mkdir -p temp/std/auth/trusted
|
||||
mkdir -p temp/std/auth/SecurityDatabase
|
||||
mkdir -p temp/std/burp
|
||||
mkdir -p temp/std/common/classes
|
||||
mkdir -p temp/std/common/config
|
||||
@ -1113,6 +1115,7 @@ mkdir -p temp/std/vulcan
|
||||
|
||||
mkdir -p temp/superclient/alice
|
||||
mkdir -p temp/superclient/auth/trusted
|
||||
mkdir -p temp/superclient/auth/SecurityDatabase
|
||||
mkdir -p temp/superclient/burp
|
||||
mkdir -p temp/superclient/common/classes
|
||||
mkdir -p temp/superclient/common/config
|
||||
@ -1156,6 +1159,7 @@ mkdir -p temp/superclient/vulcan
|
||||
|
||||
mkdir -p temp/superserver/alice
|
||||
mkdir -p temp/superserver/auth/trusted
|
||||
mkdir -p temp/superserver/auth/SecurityDatabase
|
||||
mkdir -p temp/superserver/burp
|
||||
mkdir -p temp/superserver/common/classes
|
||||
mkdir -p temp/superserver/common/config
|
||||
|
210
src/auth/Auth.cpp
Normal file
210
src/auth/Auth.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* 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 <peshkoff at mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include "../auth/Auth.h"
|
||||
#include "../jrd/ibase.h"
|
||||
|
||||
#ifdef AUTH_DEBUG
|
||||
namespace {
|
||||
void debugName(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
const char* name = "DEBUG_AUTH";
|
||||
*data = (unsigned char*)name;
|
||||
*dataSize = strlen(name);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Auth {
|
||||
|
||||
ServerInstance* DebugServer::instance()
|
||||
{
|
||||
return interfaceAlloc<DebugServerInstance>();
|
||||
}
|
||||
|
||||
ClientInstance* DebugClient::instance()
|
||||
{
|
||||
return interfaceAlloc<DebugClientInstance>();
|
||||
}
|
||||
|
||||
void DebugServer::getName(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
debugName(data, dataSize);
|
||||
}
|
||||
|
||||
void DebugClient::getName(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
debugName(data, dataSize);
|
||||
}
|
||||
|
||||
void DebugServer::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
void DebugClient::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
Result DebugServerInstance::startAuthentication(bool isService, const char* dbName,
|
||||
const unsigned char* dpb, unsigned int dpbSize,
|
||||
WriterInterface* writerInterface)
|
||||
{
|
||||
str[0] = 0;
|
||||
Firebird::ClumpletReader rdr(isService ? Firebird::ClumpletReader::spbList :
|
||||
Firebird::ClumpletReader::dpbList, dpb, dpbSize);
|
||||
if (rdr.find(isService ? isc_spb_trusted_auth : isc_dpb_trusted_auth))
|
||||
{
|
||||
memcpy(str, rdr.getBytes(), rdr.getClumpLength());
|
||||
str[rdr.getClumpLength()] = 0;
|
||||
}
|
||||
strcat((char*)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(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
*data = str;
|
||||
*dataSize = strlen((const char*)str);
|
||||
//fprintf(stderr, "DebugServerInstance::getData: %.*s\n", *dataSize, *data);
|
||||
}
|
||||
|
||||
void DebugServerInstance::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
Result DebugClientInstance::startAuthentication(bool isService, const char*, DpbInterface* dpb)
|
||||
{
|
||||
strcpy((char*)str, "HAND");
|
||||
if (dpb)
|
||||
{
|
||||
dpb->add(isService ? isc_spb_trusted_auth : isc_dpb_trusted_auth, str,
|
||||
strlen((const char*)str));
|
||||
return AUTH_SUCCESS;
|
||||
}
|
||||
return AUTH_MORE_DATA;
|
||||
}
|
||||
|
||||
Result DebugClientInstance::contAuthentication(const unsigned char* data, unsigned int size)
|
||||
{
|
||||
if (size > sizeof(data) - 1)
|
||||
{
|
||||
size = sizeof(data) - 1;
|
||||
}
|
||||
//fprintf(stderr, "DebugClientInstance::contAuthentication: %.*s\n", size, data);
|
||||
memcpy(str, data, size);
|
||||
str[size] = 0;
|
||||
strcat((char*)str, "SHAKE");
|
||||
return AUTH_CONTINUE;
|
||||
}
|
||||
|
||||
void DebugClientInstance::getData(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
*data = str;
|
||||
*dataSize = strlen((const char*)str);
|
||||
//fprintf(stderr, "DebugClientInstance::getData: %.*s\n", *dataSize, *data);
|
||||
}
|
||||
|
||||
void DebugClientInstance::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
} // namespace Auth
|
||||
#endif // AUTH_DEBUG
|
||||
|
||||
namespace Auth {
|
||||
|
||||
WriterImplementation::WriterImplementation(Firebird::MemoryPool& pool, bool svcFlag)
|
||||
: Firebird::PermanentStorage(pool), body(getPool()),
|
||||
sequence(0), tag(svcFlag ? isc_spb_auth_block : isc_dpb_auth_block)
|
||||
{ }
|
||||
|
||||
void WriterImplementation::store(Firebird::ClumpletWriter& to)
|
||||
{
|
||||
to.deleteWithTag(tag);
|
||||
to.insertBytes(tag, body.getBuffer(), body.getBufferLength());
|
||||
}
|
||||
|
||||
void WriterImplementation::reset()
|
||||
{
|
||||
body.clear();
|
||||
sequence = 0;
|
||||
}
|
||||
|
||||
void WriterImplementation::add(const char* name, const char* method, const char* details)
|
||||
{
|
||||
body.putLevel(++sequence, name, method, details);
|
||||
}
|
||||
|
||||
|
||||
DpbImplementation::DpbImplementation(Firebird::ClumpletWriter& base)
|
||||
: body(&base)
|
||||
{ }
|
||||
|
||||
int DpbImplementation::find(UCHAR tag)
|
||||
{
|
||||
return body->find(tag) ? 1 : 0;
|
||||
}
|
||||
|
||||
void DpbImplementation::add(UCHAR tag, void* bytes, unsigned int count)
|
||||
{
|
||||
body->insertBytes(tag, bytes, count);
|
||||
}
|
||||
|
||||
void DpbImplementation::drop()
|
||||
{
|
||||
body->deleteClumplet();
|
||||
}
|
||||
|
||||
|
||||
bool legacy(Plugin* plugin)
|
||||
{
|
||||
const char* legacyTrusted = "WIN_SSPI";
|
||||
const short legLength = strlen(legacyTrusted);
|
||||
UCHAR* nm;
|
||||
USHORT len;
|
||||
|
||||
plugin->getName(&nm, &len);
|
||||
|
||||
return len == legLength && memcmp(legacyTrusted, nm, legLength) == 0;
|
||||
}
|
||||
|
||||
} // namespace Auth
|
||||
|
121
src/auth/Auth.h
Normal file
121
src/auth/Auth.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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 <peshkoff at mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FB_AUTH_H
|
||||
#define FB_AUTH_H
|
||||
|
||||
#include "../auth/AuthInterface.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../common/classes/init.h"
|
||||
#include "../common/classes/array.h"
|
||||
|
||||
namespace Auth {
|
||||
|
||||
bool legacy(Plugin* plugin);
|
||||
|
||||
class WriterImplementation : public WriterInterface, public Firebird::PermanentStorage
|
||||
{
|
||||
public:
|
||||
WriterImplementation(Firebird::MemoryPool&, bool svcFlag);
|
||||
void store(Firebird::ClumpletWriter& to);
|
||||
|
||||
void reset();
|
||||
void add(const char* name, const char* method, const char* details);
|
||||
|
||||
private:
|
||||
Firebird::AuthWriter body;
|
||||
unsigned int sequence;
|
||||
unsigned char tag;
|
||||
};
|
||||
|
||||
class DpbImplementation : public DpbInterface
|
||||
{
|
||||
public:
|
||||
DpbImplementation(Firebird::ClumpletWriter& base);
|
||||
|
||||
int find(UCHAR tag);
|
||||
void add(UCHAR tag, void* bytes, unsigned int count);
|
||||
void drop();
|
||||
|
||||
private:
|
||||
Firebird::ClumpletWriter* body;
|
||||
};
|
||||
|
||||
//#define AUTH_DEBUG
|
||||
|
||||
#ifdef AUTH_DEBUG
|
||||
// The idea of debug plugin is to send some data from server to client,
|
||||
// modidy them on client and return result (which becomes login name) to the server
|
||||
|
||||
class DebugServer : public ServerPlugin
|
||||
{
|
||||
public:
|
||||
ServerInstance* instance();
|
||||
void getName(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
};
|
||||
|
||||
class DebugClient : public ClientPlugin
|
||||
{
|
||||
public:
|
||||
ClientInstance* instance();
|
||||
void getName(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
};
|
||||
|
||||
class DebugServerInstance : public ServerInstance
|
||||
{
|
||||
public:
|
||||
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(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
private:
|
||||
unsigned char str[256];
|
||||
};
|
||||
|
||||
class DebugClientInstance : public ClientInstance
|
||||
{
|
||||
public:
|
||||
Result startAuthentication(bool isService, const char* dbName, DpbInterface* dpb);
|
||||
Result contAuthentication(const unsigned char* data, unsigned int size);
|
||||
void getData(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
private:
|
||||
unsigned char str[256];
|
||||
};
|
||||
#endif // AUTH_DEBUG
|
||||
|
||||
} // namespace Auth
|
||||
|
||||
|
||||
#endif // FB_STATUS_ARG
|
136
src/auth/AuthInterface.h
Normal file
136
src/auth/AuthInterface.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* PROGRAM: Firebird authentication
|
||||
* MODULE: AuthInterface.h
|
||||
* DESCRIPTION: Interfaces, used by authentication 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 <peshkoff at mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FB_AUTH_INTERFACE
|
||||
#define FB_AUTH_INTERFACE
|
||||
|
||||
//#include "../jrd/gds_proto.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
|
||||
namespace Auth {
|
||||
|
||||
enum Result {AUTH_SUCCESS, AUTH_CONTINUE, AUTH_FAILED, AUTH_MORE_DATA};
|
||||
|
||||
class InterfaceBase
|
||||
{
|
||||
public:
|
||||
//virtual InterfaceBase* queryInterface() = 0;
|
||||
//virtual void addRef() = 0;
|
||||
virtual void release() = 0;
|
||||
protected:
|
||||
~InterfaceBase() { }
|
||||
};
|
||||
|
||||
class Auto
|
||||
{
|
||||
public:
|
||||
static void clear(InterfaceBase* ptr)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
ptr->release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T* interfaceAlloc()
|
||||
{
|
||||
/*
|
||||
void* ptr = gds__alloc(sizeof(T));
|
||||
return new(ptr) T;
|
||||
*/
|
||||
return FB_NEW(*getDefaultMemoryPool()) T;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void interfaceFree(T* ptr)
|
||||
{
|
||||
/*
|
||||
delete((void*)0) ptr;
|
||||
gds__free(ptr);
|
||||
*/
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
class WriterInterface
|
||||
{
|
||||
public:
|
||||
virtual void reset() = 0;
|
||||
virtual void add(const char* user, const char* method, const char* details) = 0;
|
||||
};
|
||||
|
||||
class DpbInterface
|
||||
{
|
||||
public:
|
||||
virtual int find(UCHAR tag) = 0;
|
||||
virtual void add(UCHAR tag, void* bytes, unsigned int count) = 0;
|
||||
virtual void drop() = 0;
|
||||
};
|
||||
|
||||
class Plugin : public InterfaceBase
|
||||
{
|
||||
public:
|
||||
virtual void getName(unsigned char** data, unsigned short* dataSize) = 0;
|
||||
};
|
||||
|
||||
class ServerInstance : public InterfaceBase
|
||||
{
|
||||
public:
|
||||
virtual Result startAuthentication(bool isService, const char* dbName,
|
||||
const unsigned char* dpb, unsigned int dpbSize,
|
||||
WriterInterface* writerInterface) = 0;
|
||||
virtual Result contAuthentication(WriterInterface* writerInterface,
|
||||
const unsigned char* data, unsigned int size) = 0;
|
||||
virtual void getData(unsigned char** data, unsigned short* dataSize) = 0;
|
||||
};
|
||||
|
||||
class ServerPlugin : public Plugin
|
||||
{
|
||||
public:
|
||||
virtual ServerInstance* instance() = 0;
|
||||
};
|
||||
|
||||
class ClientInstance : public InterfaceBase
|
||||
{
|
||||
public:
|
||||
virtual Result startAuthentication(bool isService, const char* dbName, DpbInterface* dpb) = 0;
|
||||
virtual Result contAuthentication(const unsigned char* data, unsigned int size) = 0;
|
||||
virtual void getData(unsigned char** data, unsigned short* dataSize) = 0;
|
||||
};
|
||||
|
||||
class ClientPlugin : public Plugin
|
||||
{
|
||||
public:
|
||||
virtual ClientInstance* instance() = 0;
|
||||
};
|
||||
|
||||
} // namespace Auth
|
||||
|
||||
|
||||
#endif // FB_AUTH_INTERFACE
|
73
src/auth/SecurityDatabase/LegacyClient.cpp
Normal file
73
src/auth/SecurityDatabase/LegacyClient.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* PROGRAM: Firebird authentication
|
||||
* MODULE: LegacyClient.cpp
|
||||
* DESCRIPTION: Performs legacy actions on DPB at client side.
|
||||
*
|
||||
* 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 <peshkoff at mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "firebird.h"
|
||||
#include "../jrd/ibase.h"
|
||||
#include "../auth/SecurityDatabase/LegacyClient.h"
|
||||
|
||||
namespace Auth {
|
||||
|
||||
ClientInstance* SecurityDatabaseClient::instance()
|
||||
{
|
||||
return interfaceAlloc<SecurityDatabaseClientInstance>();
|
||||
}
|
||||
|
||||
void SecurityDatabaseClient::getName(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
const char* name = "LEGACY_AUTH";
|
||||
*data = (unsigned char*)name;
|
||||
*dataSize = strlen(name);
|
||||
}
|
||||
|
||||
void SecurityDatabaseClient::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
Result SecurityDatabaseClientInstance::startAuthentication(bool, const char*, DpbInterface* dpb)
|
||||
{
|
||||
return dpb->find(isc_dpb_user_name) && (dpb->find(isc_dpb_password) ||
|
||||
dpb->find(isc_dpb_password_enc)) ?
|
||||
AUTH_SUCCESS : AUTH_CONTINUE;
|
||||
}
|
||||
|
||||
Result SecurityDatabaseClientInstance::contAuthentication(const unsigned char*, unsigned int)
|
||||
{
|
||||
return AUTH_FAILED;
|
||||
}
|
||||
|
||||
void SecurityDatabaseClientInstance::getData(unsigned char**, unsigned short* dataSize)
|
||||
{
|
||||
*dataSize = 0;
|
||||
}
|
||||
|
||||
void SecurityDatabaseClientInstance::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
} // namespace Auth
|
57
src/auth/SecurityDatabase/LegacyClient.h
Normal file
57
src/auth/SecurityDatabase/LegacyClient.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* PROGRAM: Firebird authentication
|
||||
* MODULE: LegacyClient.h
|
||||
* DESCRIPTION: Performs legacy actions on DPB at client side.
|
||||
*
|
||||
* 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 <peshkoff at mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#ifndef AUTH_LEGACY_CLIENT_H
|
||||
#define AUTH_LEGACY_CLIENT_H
|
||||
|
||||
#include "../auth/AuthInterface.h"
|
||||
|
||||
namespace Auth {
|
||||
|
||||
// Required to stop analyzing rest of plugins before first roundtrip to server
|
||||
// if legacy login is present in DPB
|
||||
|
||||
class SecurityDatabaseClient : public ClientPlugin
|
||||
{
|
||||
public:
|
||||
ClientInstance* instance();
|
||||
void getName(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
};
|
||||
|
||||
class SecurityDatabaseClientInstance : public ClientInstance
|
||||
{
|
||||
public:
|
||||
Result startAuthentication(bool isService, const char* dbName, DpbInterface* dpb);
|
||||
Result contAuthentication(const unsigned char* data, unsigned int size);
|
||||
void getData(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
};
|
||||
|
||||
} // namespace Auth
|
||||
|
||||
#endif // AUTH_LEGACY_CLIENT_H
|
@ -2,6 +2,7 @@
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
#include <../common/classes/ClumpletReader.h>
|
||||
#include <../common/classes/alloc.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -25,8 +26,17 @@ namespace
|
||||
}
|
||||
return (ToType)rc;
|
||||
}
|
||||
|
||||
void authName(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
const char* name = "WIN_SSPI";
|
||||
*data = (unsigned char*)name;
|
||||
*dataSize = strlen(name);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Auth {
|
||||
|
||||
HINSTANCE AuthSspi::library = 0;
|
||||
|
||||
bool AuthSspi::initEntries()
|
||||
@ -285,4 +295,148 @@ bool AuthSspi::getLogin(Firebird::string& login, bool& wh)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ServerInstance* WinSspiServer::instance()
|
||||
{
|
||||
return interfaceAlloc<WinSspiServerInstance>();
|
||||
}
|
||||
|
||||
ClientInstance* WinSspiClient::instance()
|
||||
{
|
||||
return interfaceAlloc<WinSspiClientInstance>();
|
||||
}
|
||||
|
||||
void WinSspiServer::getName(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
authName(data, dataSize);
|
||||
}
|
||||
|
||||
void WinSspiClient::getName(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
authName(data, dataSize);
|
||||
}
|
||||
|
||||
void WinSspiServer::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
void WinSspiClient::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
WinSspiServerInstance()
|
||||
: sspiData(), sspi(0)
|
||||
{ }
|
||||
|
||||
WinSspiClientInstance()
|
||||
: sspiData(), sspi(0)
|
||||
{ }
|
||||
|
||||
Result WinSspiServerInstance::startAuthentication(bool isService, const char* dbName,
|
||||
const unsigned char* dpb, unsigned int dpbSize,
|
||||
WriterInterface* writerInterface)
|
||||
{
|
||||
UCHAR tag = isService ? isc_spb_trusted_auth : isc_dpb_trusted_auth;
|
||||
Firebird::ClumpletReader rdr(isService ? : , dpb, dpbSize);
|
||||
if (rdr.find(tag))
|
||||
{
|
||||
sspiData.clear();
|
||||
sspiData.add(rdr.getBytes(), rdr.getClumpLength());
|
||||
if (!sspi.accept(sspiData))
|
||||
{
|
||||
return AUTH_CONTINUE;
|
||||
}
|
||||
}
|
||||
return AUTH_MORE_DATA;
|
||||
}
|
||||
|
||||
Result WinSspiServerInstance::contAuthentication(WriterInterface* writerInterface,
|
||||
const unsigned char* data, unsigned int size)
|
||||
{
|
||||
sspiData.clear();
|
||||
sspiData.add(data, size);
|
||||
sspi.accept(sspiData);
|
||||
if (!sspi.accept(sspiData))
|
||||
{
|
||||
return AUTH_FAILED;
|
||||
}
|
||||
if (!sspi.active())
|
||||
{
|
||||
bool wheel = false;
|
||||
Firebird::string login;
|
||||
sspi.getLogin(login, wheel);
|
||||
writerInterface->add(login.c_str(), "WIN_SSPI", "");
|
||||
if (wheel)
|
||||
{
|
||||
writerInterface->add("RDB$ADMIN", "WIN_SSPI", "");
|
||||
}
|
||||
return AUTH_SUCCESS;
|
||||
}
|
||||
return AUTH_MORE_DATA;
|
||||
}
|
||||
|
||||
void WinSspiServerInstance::getData(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
*data = sspiData.begin();
|
||||
*dataSize = sspiData.getCount();
|
||||
}
|
||||
|
||||
void WinSspiServerInstance::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
Result WinSspiClientInstance::startAuthentication(bool isService, const char*, DpbInterface* dpb)
|
||||
{
|
||||
sspi.request(sspiData);
|
||||
|
||||
if (dpb)
|
||||
{
|
||||
UCHAR tag = isService ? isc_spb_trusted_role : isc_dpb_trusted_role;
|
||||
while (dpb->find(tag))
|
||||
{
|
||||
dpb->drop();
|
||||
}
|
||||
tag = isService ? isc_spb_trusted_auth : isc_dpb_trusted_auth;
|
||||
while (dpb->find(tag))
|
||||
{
|
||||
dpb->drop();
|
||||
}
|
||||
|
||||
if (sspi.active())
|
||||
{
|
||||
dpb->insert(tag, sspiData.begin(), sspiData.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
return sspi.active() ? AUTH_SUCCESS : AUTH_CONTINUE;
|
||||
}
|
||||
|
||||
Result WinSspiClientInstance::contAuthentication(const unsigned char* data, unsigned int size)
|
||||
{
|
||||
sspiData.clear();
|
||||
sspiData.add(data, size);
|
||||
sspi.accept(sspiData);
|
||||
if (!sspi.accept(sspiData))
|
||||
{
|
||||
return AUTH_FAILED;
|
||||
}
|
||||
return sspi.active() ? AUTH_MORE_DATA : AUTH_CONTINUE;
|
||||
}
|
||||
|
||||
void WinSspiClientInstance::getData(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
*data = sspiData.begin();
|
||||
*dataSize = sspiData.getCount();
|
||||
}
|
||||
|
||||
void WinSspiClientInstance::release()
|
||||
{
|
||||
interfaceFree(this);
|
||||
}
|
||||
|
||||
} // namespace Auth
|
||||
|
||||
#endif // TRUSTED_AUTH
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <../common/classes/fb_string.h>
|
||||
#include <../common/classes/array.h>
|
||||
#include <../jrd/ibase.h>
|
||||
#include "../auth/AuthInterface.h"
|
||||
|
||||
#define SECURITY_WIN32
|
||||
|
||||
@ -15,6 +16,8 @@
|
||||
#include <Security.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Auth {
|
||||
|
||||
class AuthSspi
|
||||
{
|
||||
private:
|
||||
@ -65,5 +68,54 @@ public:
|
||||
bool getLogin(Firebird::string& login, bool& wh);
|
||||
};
|
||||
|
||||
class WinSspiServer : public ServerPlugin
|
||||
{
|
||||
public:
|
||||
ServerInstance* instance();
|
||||
void getName(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
};
|
||||
|
||||
class WinSspiClient : public ClientPlugin
|
||||
{
|
||||
public:
|
||||
ClientInstance* instance();
|
||||
void getName(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
};
|
||||
|
||||
class WinSspiServerInstance : public ServerInstance
|
||||
{
|
||||
public:
|
||||
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(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
|
||||
WinSspiServerInstance();
|
||||
private:
|
||||
AuthSspi::DataHolder data;
|
||||
AuthSspi sspi;
|
||||
};
|
||||
|
||||
class WinSspiClientInstance : public ClientInstance
|
||||
{
|
||||
public:
|
||||
Result startAuthentication(bool isService, const char* dbName, DpbInterface* dpb);
|
||||
Result contAuthentication(const unsigned char* data, unsigned int size);
|
||||
void getData(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
|
||||
WinSspiClientInstance();
|
||||
private:
|
||||
AuthSspi::DataHolder data;
|
||||
AuthSspi sspi;
|
||||
};
|
||||
|
||||
} // namespace Auth
|
||||
|
||||
#endif // TRUSTED_AUTH
|
||||
#endif // AUTH_SSPI_H
|
||||
|
@ -121,8 +121,20 @@ ClumpletReader::ClumpletReader(MemoryPool& pool, Kind k, const UCHAR* buffer, si
|
||||
rewind(); // this will set cur_offset and spbState
|
||||
}
|
||||
|
||||
ClumpletReader::ClumpletReader(MemoryPool& pool, const KindList* kl,
|
||||
const UCHAR* buffer, size_t buffLen, FPTR_VOID raise) :
|
||||
AutoStorage(pool), kind(kl->kind), static_buffer(buffer), static_buffer_end(buffer + buffLen)
|
||||
{
|
||||
create(kl, buffLen, raise);
|
||||
}
|
||||
|
||||
ClumpletReader::ClumpletReader(const KindList* kl, const UCHAR* buffer, size_t buffLen, FPTR_VOID raise) :
|
||||
kind(kl->kind), static_buffer(buffer), static_buffer_end(buffer + buffLen)
|
||||
{
|
||||
create(kl, buffLen, raise);
|
||||
}
|
||||
|
||||
void ClumpletReader::create(const KindList* kl, size_t buffLen, FPTR_VOID raise)
|
||||
{
|
||||
if (buffLen)
|
||||
{
|
||||
@ -715,4 +727,68 @@ const ClumpletReader::KindList ClumpletReader::dpbList[] = {
|
||||
{ClumpletReader::EndOfList, 0}
|
||||
};
|
||||
|
||||
const ClumpletReader::KindList ClumpletReader::spbList[] = {
|
||||
{ClumpletReader::SpbAttach, isc_spb_current_version},
|
||||
{ClumpletReader::SpbAttach, isc_spb_version1},
|
||||
{ClumpletReader::WideTagged, isc_spb_version3},
|
||||
{ClumpletReader::EndOfList, 0}
|
||||
};
|
||||
|
||||
AuthReader::AuthReader(const AuthBlock& authBlock)
|
||||
: ClumpletReader(ClumpletReader::WideUnTagged, authBlock.begin(), authBlock.getCount())
|
||||
{
|
||||
rewind();
|
||||
}
|
||||
|
||||
bool AuthReader::getInfo(string* name, string* method, string* details)
|
||||
{
|
||||
if (isEof())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name)
|
||||
{
|
||||
*name = "";
|
||||
}
|
||||
if (method)
|
||||
{
|
||||
*method = "";
|
||||
}
|
||||
if (details)
|
||||
{
|
||||
*details = "";
|
||||
}
|
||||
|
||||
ClumpletReader internal(WideUnTagged, getBytes(), getClumpLength());
|
||||
for (internal.rewind(); !internal.isEof(); internal.moveNext())
|
||||
{
|
||||
switch(internal.getClumpTag())
|
||||
{
|
||||
case AUTH_NAME:
|
||||
if (name)
|
||||
{
|
||||
internal.getString(*name);
|
||||
}
|
||||
break;
|
||||
case AUTH_METHOD:
|
||||
if (method)
|
||||
{
|
||||
internal.getString(*method);
|
||||
}
|
||||
break;
|
||||
case AUTH_DETAILS:
|
||||
if (details)
|
||||
{
|
||||
internal.getString(*details);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
ClumpletReader(MemoryPool& pool, Kind k, const UCHAR* buffer, size_t buffLen);
|
||||
// Different versions of clumplets may have different kinds
|
||||
ClumpletReader(const KindList* kl, const UCHAR* buffer, size_t buffLen, FPTR_VOID raise = NULL);
|
||||
ClumpletReader(MemoryPool& pool, const KindList* kl, const UCHAR* buffer, size_t buffLen, FPTR_VOID raise = NULL);
|
||||
virtual ~ClumpletReader() { }
|
||||
|
||||
// Navigation in clumplet buffer
|
||||
@ -152,9 +153,22 @@ private:
|
||||
const UCHAR* static_buffer_end;
|
||||
|
||||
static SINT64 fromVaxInteger(const UCHAR* ptr, size_t length);
|
||||
void create(const KindList* kl, size_t buffLen, FPTR_VOID raise);
|
||||
|
||||
public:
|
||||
static const KindList dpbList[]; // Some frequently used kind lists
|
||||
static const KindList spbList[]; // Some frequently used kind lists
|
||||
};
|
||||
|
||||
class AuthReader : public ClumpletReader
|
||||
{
|
||||
public:
|
||||
typedef Array<UCHAR> AuthBlock;
|
||||
enum Tag {AUTH_NAME, AUTH_METHOD, AUTH_DETAILS};
|
||||
|
||||
AuthReader(const AuthBlock& authBlock);
|
||||
|
||||
bool getInfo(string* name, string* method = 0, string* details = 0);
|
||||
};
|
||||
|
||||
} // namespace Firebird
|
||||
|
@ -81,8 +81,28 @@ void ClumpletWriter::initNewBuffer(UCHAR tag)
|
||||
}
|
||||
}
|
||||
|
||||
ClumpletWriter::ClumpletWriter(Kind k, size_t limit, const UCHAR* buffer, size_t buffLen, UCHAR tag) :
|
||||
ClumpletReader(k, NULL, 0), sizeLimit(limit), kindList(NULL), dynamic_buffer(getPool())
|
||||
ClumpletWriter::ClumpletWriter(Kind k, size_t limit, const UCHAR* buffer, size_t buffLen, UCHAR tag)
|
||||
: ClumpletReader(k, NULL, 0), sizeLimit(limit), kindList(NULL), dynamic_buffer(getPool())
|
||||
{
|
||||
create(buffer, buffLen, tag);
|
||||
}
|
||||
|
||||
ClumpletWriter::ClumpletWriter(MemoryPool& pool, const KindList* kl, size_t limit,
|
||||
const UCHAR* buffer, size_t buffLen)
|
||||
: ClumpletReader(pool, kl, buffer, buffLen), sizeLimit(limit),
|
||||
kindList(kl), dynamic_buffer(getPool())
|
||||
{
|
||||
create(buffer, buffLen, kl->tag);
|
||||
}
|
||||
|
||||
ClumpletWriter::ClumpletWriter(const KindList* kl, size_t limit, const UCHAR* buffer, size_t buffLen) :
|
||||
ClumpletReader(kl, buffer, buffLen), sizeLimit(limit), kindList(kl), dynamic_buffer(getPool())
|
||||
{
|
||||
create(buffer, buffLen, kl->tag);
|
||||
}
|
||||
|
||||
|
||||
void ClumpletWriter::create(const UCHAR* buffer, size_t buffLen, UCHAR tag)
|
||||
{
|
||||
if (buffer && buffLen) {
|
||||
dynamic_buffer.push(buffer, buffLen);
|
||||
@ -93,18 +113,6 @@ ClumpletWriter::ClumpletWriter(Kind k, size_t limit, const UCHAR* buffer, size_t
|
||||
rewind();
|
||||
}
|
||||
|
||||
ClumpletWriter::ClumpletWriter(const KindList* kl, size_t limit, const UCHAR* buffer, size_t buffLen) :
|
||||
ClumpletReader(kl, buffer, buffLen), sizeLimit(limit), kindList(kl), dynamic_buffer(getPool())
|
||||
{
|
||||
if (buffer && buffLen) {
|
||||
dynamic_buffer.push(buffer, buffLen);
|
||||
}
|
||||
else {
|
||||
initNewBuffer(kl->tag);
|
||||
}
|
||||
rewind();
|
||||
}
|
||||
|
||||
/*
|
||||
ClumpletWriter::ClumpletWriter(MemoryPool& given_pool, Kind k, size_t limit,
|
||||
const UCHAR* buffer, size_t buffLen, UCHAR tag) :
|
||||
@ -227,10 +235,10 @@ void ClumpletWriter::insertPath(UCHAR tag, const PathName& str)
|
||||
|
||||
void ClumpletWriter::insertString(UCHAR tag, const char* str, size_t length)
|
||||
{
|
||||
insertBytesLengthCheck(tag, reinterpret_cast<const UCHAR*>(str), length);
|
||||
insertBytesLengthCheck(tag, str, length);
|
||||
}
|
||||
|
||||
void ClumpletWriter::insertBytes(UCHAR tag, const UCHAR* bytes, size_t length)
|
||||
void ClumpletWriter::insertBytes(UCHAR tag, const void* bytes, size_t length)
|
||||
{
|
||||
insertBytesLengthCheck(tag, bytes, length);
|
||||
}
|
||||
@ -240,7 +248,7 @@ void ClumpletWriter::insertByte(UCHAR tag, const UCHAR byte)
|
||||
insertBytesLengthCheck(tag, &byte, 1);
|
||||
}
|
||||
|
||||
void ClumpletWriter::insertBytesLengthCheck(UCHAR tag, const UCHAR* bytes, const size_t length)
|
||||
void ClumpletWriter::insertBytesLengthCheck(UCHAR tag, const void* bytes, const size_t length)
|
||||
{
|
||||
// Check that we're not beyond the end of buffer.
|
||||
// We get there when we set end marker.
|
||||
@ -348,7 +356,7 @@ void ClumpletWriter::insertBytesLengthCheck(UCHAR tag, const UCHAR* bytes, const
|
||||
}
|
||||
break;
|
||||
}
|
||||
dynamic_buffer.insert(cur_offset, bytes, length);
|
||||
dynamic_buffer.insert(cur_offset, reinterpret_cast<const UCHAR*>(bytes), length);
|
||||
const size_t new_offset = cur_offset + length;
|
||||
cur_offset = saved_offset;
|
||||
adjustSpbState();
|
||||
@ -476,4 +484,28 @@ void ClumpletWriter::insertClumplet(const SingleClumplet& clumplet)
|
||||
insertBytes(clumplet.tag, clumplet.data, clumplet.size);
|
||||
}
|
||||
|
||||
void ClumpletWriter::clear()
|
||||
{
|
||||
reset(getBufferTag());
|
||||
}
|
||||
|
||||
void AuthWriter::putLevel(USHORT num, const char* name, const char* method, const char* details)
|
||||
{
|
||||
ClumpletWriter internal(WideUnTagged, MAX_DPB_SIZE);
|
||||
if (name)
|
||||
{
|
||||
internal.insertString(AuthReader::AUTH_NAME, name);
|
||||
}
|
||||
if (method)
|
||||
{
|
||||
internal.insertString(AuthReader::AUTH_METHOD, method);
|
||||
}
|
||||
if (details)
|
||||
{
|
||||
internal.insertString(AuthReader::AUTH_DETAILS, details);
|
||||
}
|
||||
|
||||
insertBytes(num, internal.getBuffer(), internal.getBufferLength());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -53,14 +53,17 @@ public:
|
||||
|
||||
// Create writer from a given buffer with possibly different clumplet version
|
||||
ClumpletWriter(const KindList* kl, size_t limit, const UCHAR* buffer = NULL, size_t buffLen = 0);
|
||||
ClumpletWriter(MemoryPool& pool, const KindList* kl, size_t limit,
|
||||
const UCHAR* buffer = NULL, size_t buffLen = 0);
|
||||
|
||||
void reset(UCHAR tag);
|
||||
void reset(const UCHAR* buffer, const size_t buffLen);
|
||||
void clear();
|
||||
|
||||
// Methods to create new clumplet at current position
|
||||
void insertInt(UCHAR tag, const SLONG value);
|
||||
void insertBigInt(UCHAR tag, const SINT64 value);
|
||||
void insertBytes(UCHAR tag, const UCHAR* bytes, size_t length);
|
||||
void insertBytes(UCHAR tag, const void* bytes, size_t length);
|
||||
void insertString(UCHAR tag, const string& str);
|
||||
void insertPath(UCHAR tag, const PathName& str);
|
||||
void insertString(UCHAR tag, const char* str, size_t length);
|
||||
@ -85,7 +88,7 @@ public:
|
||||
protected:
|
||||
virtual const UCHAR* getBufferEnd() const;
|
||||
virtual void size_overflow();
|
||||
void insertBytesLengthCheck(UCHAR tag, const UCHAR* bytes, const size_t length);
|
||||
void insertBytesLengthCheck(UCHAR tag, const void* bytes, const size_t length);
|
||||
bool upgradeVersion(); // upgrade clumplet version - obtain newest from kindList
|
||||
|
||||
private:
|
||||
@ -98,9 +101,18 @@ private:
|
||||
HalfStaticArray<UCHAR, 128> dynamic_buffer;
|
||||
|
||||
void initNewBuffer(UCHAR tag);
|
||||
void create(const UCHAR* buffer, size_t buffLen, UCHAR tag);
|
||||
static void toVaxInteger(UCHAR* ptr, size_t length, const SINT64 value);
|
||||
};
|
||||
|
||||
class AuthWriter : public ClumpletWriter
|
||||
{
|
||||
public:
|
||||
AuthWriter(MemoryPool& pool) : ClumpletWriter(pool, ClumpletWriter::WideUnTagged, MAX_DPB_SIZE)
|
||||
{ }
|
||||
void putLevel(USHORT num, const char* name, const char* method, const char* details);
|
||||
};
|
||||
|
||||
} // namespace Firebird
|
||||
|
||||
#endif // CLUMPLETWRITER_H
|
||||
|
@ -88,6 +88,11 @@ public:
|
||||
return !ptr;
|
||||
}
|
||||
|
||||
bool hasData() const
|
||||
{
|
||||
return ptr != NULL;
|
||||
}
|
||||
|
||||
Where* operator->()
|
||||
{
|
||||
return ptr;
|
||||
|
@ -111,6 +111,7 @@
|
||||
#define isc_dpb_org_filename 76
|
||||
#define isc_dpb_utf8_filename 77
|
||||
#define isc_dpb_ext_call_depth 78
|
||||
#define isc_dpb_auth_block 79
|
||||
|
||||
/**************************************************/
|
||||
/* clumplet tags used inside isc_dpb_address_path */
|
||||
@ -248,6 +249,7 @@
|
||||
#define isc_spb_version1 1
|
||||
#define isc_spb_current_version 2
|
||||
#define isc_spb_version isc_spb_current_version
|
||||
#define isc_spb_version3 3
|
||||
#define isc_spb_user_name isc_dpb_user_name
|
||||
#define isc_spb_sys_user_name isc_dpb_sys_user_name
|
||||
#define isc_spb_sys_user_name_enc isc_dpb_sys_user_name_enc
|
||||
@ -263,6 +265,7 @@
|
||||
#define isc_spb_process_name 112
|
||||
#define isc_spb_trusted_role 113
|
||||
#define isc_spb_verbint 114
|
||||
#define isc_spb_auth_block 115
|
||||
|
||||
|
||||
#define isc_spb_connect_timeout isc_dpb_connect_timeout
|
||||
|
@ -39,7 +39,7 @@ UserManagement::UserManagement(jrd_tra* tra)
|
||||
: database(0), transaction(0), commands(*tra->tra_pool)
|
||||
{
|
||||
char securityDatabaseName[MAXPATHLEN];
|
||||
SecurityDatabase::getPath(securityDatabaseName);
|
||||
Auth::SecurityDatabase::getPath(securityDatabaseName);
|
||||
ISC_STATUS_ARRAY status;
|
||||
Attachment* att = tra->tra_attachment;
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "../jrd/ibase.h"
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
#include "../jrd/gds_proto.h"
|
||||
#include "../jrd/utl_proto.h"
|
||||
#include "../jrd/why_proto.h"
|
||||
|
@ -76,7 +76,6 @@
|
||||
#include "../jrd/vio_proto.h"
|
||||
#include "../jrd/thread_proto.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
#include "../utilities/gsec/gsec.h"
|
||||
#include "../jrd/msg_encode.h"
|
||||
|
||||
|
@ -64,7 +64,6 @@
|
||||
#include "../jrd/jrd.h"
|
||||
#include "../jrd/err_proto.h"
|
||||
#include "../jrd/thread_proto.h"
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
#include "../common/classes/fb_tls.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/utils_proto.h"
|
||||
|
113
src/jrd/jrd.cpp
113
src/jrd/jrd.cpp
@ -77,6 +77,7 @@
|
||||
#include "../intl/charsets.h"
|
||||
#include "../jrd/sort.h"
|
||||
#include "../jrd/PreparedStatement.h"
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
|
||||
#include "../jrd/blb_proto.h"
|
||||
#include "../jrd/cch_proto.h"
|
||||
@ -455,7 +456,6 @@ public:
|
||||
SLONG dpb_remote_pid;
|
||||
bool dpb_no_db_triggers;
|
||||
bool dpb_gbak_attach;
|
||||
bool dpb_trusted_role;
|
||||
bool dpb_utf8_filename;
|
||||
ULONG dpb_ext_call_depth;
|
||||
ULONG dpb_flags; // to OR'd with dbb_flags
|
||||
@ -465,8 +465,7 @@ public:
|
||||
// MUST be FIRST
|
||||
string dpb_sys_user_name;
|
||||
string dpb_user_name;
|
||||
string dpb_password;
|
||||
string dpb_password_enc;
|
||||
AuthReader::AuthBlock dpb_auth_block;
|
||||
string dpb_role_name;
|
||||
string dpb_journal;
|
||||
string dpb_key;
|
||||
@ -902,7 +901,6 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
UserId userId;
|
||||
DatabaseOptions options;
|
||||
bool invalid_client_SQL_dialect = false;
|
||||
SecurityDatabase::InitHolder siHolder;
|
||||
PathName file_name, expanded_name;
|
||||
bool is_alias = false;
|
||||
|
||||
@ -954,13 +952,6 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
// Check for correct credentials supplied
|
||||
getUserInfo(userId, options);
|
||||
}
|
||||
catch (const DelayFailedLogin& ex)
|
||||
{
|
||||
trace_failed_attach(NULL, filename, options, false, true);
|
||||
|
||||
ex.sleep();
|
||||
return ex.stuff_exception(user_status);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
trace_failed_attach(NULL, filename, options, false, true);
|
||||
@ -1536,7 +1527,6 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
return unwindAttach(tdbb, ex, user_status, attachment, dbb);
|
||||
}
|
||||
|
||||
siHolder.clear();
|
||||
return FB_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1986,7 +1976,6 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
|
||||
UserId userId;
|
||||
DatabaseOptions options;
|
||||
SecurityDatabase::InitHolder siHolder;
|
||||
PathName file_name, expanded_name;
|
||||
bool is_alias = false;
|
||||
|
||||
@ -2043,13 +2032,6 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
// Check for correct credentials supplied
|
||||
getUserInfo(userId, options);
|
||||
}
|
||||
catch (const DelayFailedLogin& ex)
|
||||
{
|
||||
trace_failed_attach(NULL, filename, options, true, true);
|
||||
|
||||
ex.sleep();
|
||||
return ex.stuff_exception(user_status);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
trace_failed_attach(NULL, filename, options, true, true);
|
||||
@ -2333,7 +2315,6 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
return unwindAttach(tdbb, ex, user_status, attachment, dbb);
|
||||
}
|
||||
|
||||
siHolder.clear();
|
||||
return FB_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2462,8 +2443,6 @@ ISC_STATUS GDS_DETACH(ISC_STATUS* user_status, Jrd::Attachment** handle)
|
||||
}
|
||||
|
||||
*handle = NULL;
|
||||
|
||||
SecurityDatabase::shutdown();
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
@ -3341,11 +3320,6 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status,
|
||||
|
||||
*svc_handle = new Service(service_name, spb_length, reinterpret_cast<const UCHAR*>(spb));
|
||||
}
|
||||
catch (const DelayFailedLogin& ex)
|
||||
{
|
||||
ex.sleep();
|
||||
return ex.stuff_exception(user_status);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
return ex.stuff_exception(user_status);
|
||||
@ -4893,33 +4867,22 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
|
||||
break;
|
||||
|
||||
case isc_dpb_sql_role_name:
|
||||
if (! dpb_trusted_role)
|
||||
{
|
||||
getString(rdr, dpb_role_name);
|
||||
}
|
||||
getString(rdr, dpb_role_name);
|
||||
break;
|
||||
|
||||
case isc_dpb_auth_block:
|
||||
dpb_auth_block.clear();
|
||||
dpb_auth_block.add(rdr.getBytes(), rdr.getClumpLength());
|
||||
break;
|
||||
|
||||
case isc_dpb_user_name:
|
||||
getString(rdr, dpb_user_name);
|
||||
break;
|
||||
|
||||
case isc_dpb_password:
|
||||
getString(rdr, dpb_password);
|
||||
break;
|
||||
|
||||
case isc_dpb_password_enc:
|
||||
rdr.getString(dpb_password_enc);
|
||||
break;
|
||||
|
||||
case isc_dpb_trusted_auth:
|
||||
getString(rdr, dpb_trusted_login);
|
||||
break;
|
||||
|
||||
case isc_dpb_trusted_role:
|
||||
dpb_trusted_role = true;
|
||||
getString(rdr, dpb_role_name);
|
||||
break;
|
||||
|
||||
case isc_dpb_encrypt_key:
|
||||
#ifdef ISC_DATABASE_ENCRYPTION
|
||||
rdr.getString(dpb_key);
|
||||
@ -6228,7 +6191,7 @@ static VdnResult verifyDatabaseName(const PathName& name, ISC_STATUS* status, bo
|
||||
MutexLockGuard guard(mutex);
|
||||
|
||||
if (! securityNameBuffer[0]) {
|
||||
SecurityDatabase::getPath(securityNameBuffer);
|
||||
Auth::SecurityDatabase::getPath(securityNameBuffer);
|
||||
expandedSecurityNameBuffer->assign(securityNameBuffer);
|
||||
ISC_expand_filename(expandedSecurityNameBuffer, false);
|
||||
}
|
||||
@ -6251,9 +6214,8 @@ static VdnResult verifyDatabaseName(const PathName& name, ISC_STATUS* status, bo
|
||||
|
||||
getUserInfo
|
||||
|
||||
@brief Checks the userinfo database to validate
|
||||
password to that passed in.
|
||||
Takes into account possible trusted authentication.
|
||||
@brief Almost stub-like now.
|
||||
Planned to take into an account mapping of users and groups.
|
||||
Fills UserId structure with resulting values.
|
||||
|
||||
@param user
|
||||
@ -6263,8 +6225,7 @@ static VdnResult verifyDatabaseName(const PathName& name, ISC_STATUS* status, bo
|
||||
static void getUserInfo(UserId& user, const DatabaseOptions& options)
|
||||
{
|
||||
int id = -1, group = -1; // CVC: This var contained trash
|
||||
int node_id = 0;
|
||||
string name;
|
||||
string name, trusted_role;
|
||||
|
||||
#ifdef BOOT_BUILD
|
||||
bool wheel = true;
|
||||
@ -6274,29 +6235,29 @@ static void getUserInfo(UserId& user, const DatabaseOptions& options)
|
||||
{
|
||||
name = options.dpb_trusted_login;
|
||||
}
|
||||
else if (options.dpb_user_name.hasData())
|
||||
{
|
||||
name = options.dpb_user_name;
|
||||
}
|
||||
else if (options.dpb_auth_block.hasData())
|
||||
{
|
||||
// stub instead mapUser(....);
|
||||
AuthReader auth(options.dpb_auth_block);
|
||||
if (auth.getInfo(&name))
|
||||
{
|
||||
auth.moveNext();
|
||||
auth.getInfo(&trusted_role);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (options.dpb_user_name.isEmpty() &&
|
||||
options.dpb_network_protocol.isEmpty() && // This 2 checks ensure that we are not remote server
|
||||
options.dpb_remote_address.isEmpty()) // process, i.e. can use unix OS auth.
|
||||
string s(options.dpb_sys_user_name);
|
||||
ISC_utf8ToSystem(s);
|
||||
wheel = ISC_get_user(&name, &id, &group, s.nullStr());
|
||||
ISC_systemToUtf8(name);
|
||||
if (id == 0)
|
||||
{
|
||||
string s(options.dpb_sys_user_name);
|
||||
ISC_utf8ToSystem(s);
|
||||
wheel = ISC_get_user(&name, &id, &group, s.nullStr());
|
||||
ISC_systemToUtf8(name);
|
||||
}
|
||||
|
||||
if (options.dpb_user_name.hasData() || (id == -1))
|
||||
{
|
||||
const string remote = options.dpb_network_protocol +
|
||||
(options.dpb_network_protocol.isEmpty() || options.dpb_remote_address.isEmpty() ? "" : "/") +
|
||||
options.dpb_remote_address;
|
||||
|
||||
SecurityDatabase::verifyUser(name,
|
||||
options.dpb_user_name.nullStr(),
|
||||
options.dpb_password.nullStr(),
|
||||
options.dpb_password_enc.nullStr(),
|
||||
&id, &group, &node_id, remote);
|
||||
wheel = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6327,17 +6288,21 @@ static void getUserInfo(UserId& user, const DatabaseOptions& options)
|
||||
user.usr_user_name = name;
|
||||
user.usr_project_name = "";
|
||||
user.usr_org_name = "";
|
||||
user.usr_sql_role_name = options.dpb_role_name;
|
||||
user.usr_user_id = id;
|
||||
user.usr_group_id = group;
|
||||
user.usr_node_id = node_id;
|
||||
|
||||
if (wheel)
|
||||
{
|
||||
user.usr_flags |= USR_locksmith;
|
||||
}
|
||||
|
||||
if (options.dpb_trusted_role)
|
||||
if (options.dpb_role_name.hasData())
|
||||
{
|
||||
user.usr_sql_role_name = options.dpb_role_name;
|
||||
}
|
||||
else if (trusted_role.hasData())
|
||||
{
|
||||
user.usr_sql_role_name = trusted_role;
|
||||
user.usr_flags |= USR_trole;
|
||||
}
|
||||
}
|
||||
|
@ -31,40 +31,36 @@
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../jrd/sha.h"
|
||||
#include "gen/iberror.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
|
||||
#include "../auth/AuthInterface.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
namespace Auth {
|
||||
|
||||
const size_t MAX_PASSWORD_ENC_LENGTH = 12; // passed by remote protocol
|
||||
const size_t MAX_PASSWORD_LENGTH = 64; // used to store passwords internally
|
||||
static const char* const PASSWORD_SALT = "9z"; // for old ENC_crypt()
|
||||
const size_t SALT_LENGTH = 12; // measured after base64 coding
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
class SecurityDatabase
|
||||
{
|
||||
struct user_record
|
||||
{
|
||||
SLONG gid;
|
||||
SLONG uid;
|
||||
SSHORT flag;
|
||||
SCHAR password[MAX_PASSWORD_LENGTH + 2];
|
||||
};
|
||||
|
||||
public:
|
||||
static void getPath(TEXT* path_buffer)
|
||||
static void getPath(char* path_buffer)
|
||||
{
|
||||
static const char* USER_INFO_NAME = "security2.fdb";
|
||||
Firebird::PathName name = fb_utils::getPrefix(fb_utils::FB_DIR_SECDB, USER_INFO_NAME);
|
||||
name.copyTo(path_buffer, MAXPATHLEN);
|
||||
}
|
||||
|
||||
static void initialize();
|
||||
static void shutdown();
|
||||
static void verifyUser(Firebird::string&, const TEXT*, const TEXT*, const TEXT*,
|
||||
int*, int*, int*, const Firebird::string&);
|
||||
static Result verify(WriterInterface* authBlock,
|
||||
Firebird::ClumpletReader& originalDpb);
|
||||
|
||||
static void Shutdown(void*);
|
||||
|
||||
static void hash(Firebird::string& h, const Firebird::string& userName, const TEXT* passwd)
|
||||
{
|
||||
@ -75,7 +71,7 @@ public:
|
||||
|
||||
static void hash(Firebird::string& h,
|
||||
const Firebird::string& userName,
|
||||
const TEXT* passwd,
|
||||
const Firebird::string& passwd,
|
||||
const Firebird::string& oldHash)
|
||||
{
|
||||
Firebird::string salt(oldHash);
|
||||
@ -88,9 +84,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static const UCHAR PWD_REQUEST[256];
|
||||
static const UCHAR TPB[4];
|
||||
|
||||
Firebird::Mutex mutex;
|
||||
|
||||
ISC_STATUS_ARRAY status;
|
||||
@ -98,65 +91,44 @@ private:
|
||||
isc_db_handle lookup_db;
|
||||
isc_req_handle lookup_req;
|
||||
|
||||
int counter;
|
||||
int timer;
|
||||
char user_info_name[MAXPATHLEN];
|
||||
|
||||
void fini();
|
||||
void init();
|
||||
bool lookup_user(const TEXT*, int*, int*, TEXT*);
|
||||
void fini();
|
||||
bool lookup_user(const char*, char*);
|
||||
void prepare();
|
||||
void checkStatus(const char* callName, ISC_STATUS userError = isc_psw_db_error);
|
||||
|
||||
static SecurityDatabase instance;
|
||||
|
||||
SecurityDatabase()
|
||||
: lookup_db(0), lookup_req(0), counter(0)
|
||||
{}
|
||||
|
||||
public:
|
||||
// Shuts SecurityDatabase in case of errors during attach or create.
|
||||
// When attachment is created, control is passed to it using clear.
|
||||
class InitHolder
|
||||
: lookup_db(0), lookup_req(0), timer(0)
|
||||
{
|
||||
public:
|
||||
InitHolder()
|
||||
: shutdown(true)
|
||||
{
|
||||
SecurityDatabase::initialize();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
shutdown = false;
|
||||
}
|
||||
|
||||
~InitHolder()
|
||||
{
|
||||
if (shutdown)
|
||||
{
|
||||
SecurityDatabase::shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool shutdown;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class DelayFailedLogin : public Firebird::Exception
|
||||
class SecurityDatabaseServer : public ServerPlugin
|
||||
{
|
||||
private:
|
||||
int seconds;
|
||||
|
||||
public:
|
||||
explicit DelayFailedLogin(int sec) throw() : Exception(), seconds(sec) { }
|
||||
|
||||
virtual ISC_STATUS stuff_exception(ISC_STATUS* const status_vector) const throw();
|
||||
virtual const char* what() const throw() { return "Jrd::DelayFailedLogin"; }
|
||||
static void raise(int sec);
|
||||
void sleep() const;
|
||||
ServerInstance* instance();
|
||||
void getName(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
};
|
||||
|
||||
class SecurityDatabaseServerInstance : public ServerInstance
|
||||
{
|
||||
public:
|
||||
|
||||
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(unsigned char** data, unsigned short* dataSize);
|
||||
void release();
|
||||
};
|
||||
|
||||
} // namespace Jrd
|
||||
} // namespace Auth
|
||||
|
||||
#endif // JRD_PWD_H
|
||||
|
448
src/jrd/pwd.cpp
448
src/jrd/pwd.cpp
@ -41,14 +41,89 @@
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include "../common/classes/init.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
|
||||
using namespace Jrd;
|
||||
using namespace Firebird;
|
||||
|
||||
namespace {
|
||||
|
||||
// temporal implementation of timer
|
||||
|
||||
GlobalPtr<Mutex> timerMutex;
|
||||
FPTR_VOID_PTR toRun = 0;
|
||||
unsigned int cnt = 0;
|
||||
|
||||
int active = 0;
|
||||
|
||||
int stopTimer(const int, const int mask, void*)
|
||||
{
|
||||
switch(mask)
|
||||
{
|
||||
case fb_shut_preproviders:
|
||||
active = 2;
|
||||
break;
|
||||
case fb_shut_finish:
|
||||
while (active == 2)
|
||||
{
|
||||
THREAD_SLEEP(10);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
THREAD_ENTRY_DECLARE threadTimer(THREAD_ENTRY_PARAM)
|
||||
{
|
||||
while(active == 1)
|
||||
{
|
||||
{
|
||||
MutexLockGuard g(timerMutex);
|
||||
if (cnt == 0)
|
||||
{
|
||||
if (toRun)
|
||||
{
|
||||
toRun(0);
|
||||
toRun = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
--cnt;
|
||||
}
|
||||
}
|
||||
|
||||
THREAD_SLEEP(100);
|
||||
}
|
||||
|
||||
active = 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fb_alloc_timer()
|
||||
{
|
||||
if (! active)
|
||||
{
|
||||
active = 1;
|
||||
gds__thread_start(threadTimer, 0, 0, 0, 0);
|
||||
fb_shutdown_callback(0, stopTimer, fb_shut_preproviders | fb_shut_finish, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void fb_thread_timer(int, int delay, FPTR_VOID_PTR function, void*)
|
||||
{
|
||||
MutexLockGuard g(timerMutex);
|
||||
|
||||
cnt = delay / 100;
|
||||
if (! cnt)
|
||||
{
|
||||
cnt = 1;
|
||||
}
|
||||
toRun = function;
|
||||
}
|
||||
|
||||
// BLR to search database for user name record
|
||||
|
||||
const UCHAR SecurityDatabase::PWD_REQUEST[] =
|
||||
const UCHAR PWD_REQUEST[] =
|
||||
{
|
||||
blr_version5,
|
||||
blr_begin,
|
||||
@ -56,7 +131,7 @@ const UCHAR SecurityDatabase::PWD_REQUEST[] =
|
||||
blr_long, 0,
|
||||
blr_long, 0,
|
||||
blr_short, 0,
|
||||
blr_text, BLR_WORD(MAX_PASSWORD_LENGTH + 2),
|
||||
blr_text, BLR_WORD(Auth::MAX_PASSWORD_LENGTH + 2),
|
||||
blr_message, 0, 1, 0,
|
||||
blr_cstring, 129, 0,
|
||||
blr_receive, 0,
|
||||
@ -95,9 +170,19 @@ const UCHAR SecurityDatabase::PWD_REQUEST[] =
|
||||
blr_eoc
|
||||
};
|
||||
|
||||
// Returns data in the following format
|
||||
|
||||
struct user_record
|
||||
{
|
||||
SLONG gid;
|
||||
SLONG uid;
|
||||
SSHORT flag;
|
||||
SCHAR password[Auth::MAX_PASSWORD_LENGTH + 2];
|
||||
};
|
||||
|
||||
// Transaction parameter buffer
|
||||
|
||||
const UCHAR SecurityDatabase::TPB[4] =
|
||||
const UCHAR TPB[4] =
|
||||
{
|
||||
isc_tpb_version1,
|
||||
isc_tpb_read,
|
||||
@ -105,119 +190,14 @@ const UCHAR SecurityDatabase::TPB[4] =
|
||||
isc_tpb_wait
|
||||
};
|
||||
|
||||
} // anonymous
|
||||
|
||||
namespace Auth {
|
||||
|
||||
// Static instance of the database
|
||||
|
||||
SecurityDatabase SecurityDatabase::instance;
|
||||
|
||||
#ifndef EMBEDDED
|
||||
namespace {
|
||||
// Disable attempts to brute-force logins/passwords
|
||||
class FailedLogin
|
||||
{
|
||||
public:
|
||||
string login;
|
||||
int failCount;
|
||||
time_t lastAttempt;
|
||||
|
||||
explicit FailedLogin(const string& l)
|
||||
: login(l), failCount(1), lastAttempt(time(0))
|
||||
{}
|
||||
|
||||
FailedLogin(MemoryPool& p, const FailedLogin& fl)
|
||||
: login(p, fl.login), failCount(fl.failCount), lastAttempt(fl.lastAttempt)
|
||||
{}
|
||||
|
||||
static const string* generate(const void* /*sender*/, const FailedLogin* f)
|
||||
{
|
||||
return &f->login;
|
||||
}
|
||||
};
|
||||
|
||||
const size_t MAX_CONCURRENT_FAILURES = 16;
|
||||
const int MAX_FAILED_ATTEMPTS = 4;
|
||||
const int FAILURE_DELAY = 8; // seconds
|
||||
|
||||
class FailedLogins : private SortedObjectsArray<FailedLogin,
|
||||
InlineStorage<FailedLogin*, MAX_CONCURRENT_FAILURES>,
|
||||
const string, FailedLogin>
|
||||
{
|
||||
private:
|
||||
// as long as we have voluntary threads scheduler,
|
||||
// this mutex should be entered AFTER that scheduler entered!
|
||||
Mutex fullAccess;
|
||||
|
||||
typedef SortedObjectsArray<FailedLogin,
|
||||
InlineStorage<FailedLogin*, MAX_CONCURRENT_FAILURES>,
|
||||
const string, FailedLogin> inherited;
|
||||
|
||||
public:
|
||||
explicit FailedLogins(MemoryPool& p)
|
||||
: inherited(p)
|
||||
{}
|
||||
|
||||
void loginFail(const string& login)
|
||||
{
|
||||
MutexLockGuard guard(fullAccess);
|
||||
|
||||
const time_t t = time(0);
|
||||
|
||||
size_t pos;
|
||||
if (find(login, pos))
|
||||
{
|
||||
FailedLogin& l = (*this)[pos];
|
||||
if (t - l.lastAttempt >= FAILURE_DELAY)
|
||||
{
|
||||
l.failCount = 0;
|
||||
}
|
||||
l.lastAttempt = t;
|
||||
if (++l.failCount >= MAX_FAILED_ATTEMPTS)
|
||||
{
|
||||
l.failCount = 0;
|
||||
Jrd::DelayFailedLogin::raise(FAILURE_DELAY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (getCount() >= MAX_CONCURRENT_FAILURES)
|
||||
{
|
||||
// try to perform old entries collection
|
||||
for (iterator i = begin(); i != end(); )
|
||||
{
|
||||
if (t - i->lastAttempt >= FAILURE_DELAY)
|
||||
{
|
||||
remove(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getCount() >= MAX_CONCURRENT_FAILURES)
|
||||
{
|
||||
// it seems we are under attack - too many wrong logins !!!
|
||||
Jrd::DelayFailedLogin::raise(FAILURE_DELAY);
|
||||
}
|
||||
|
||||
add(FailedLogin(login));
|
||||
}
|
||||
|
||||
void loginSuccess(const string& login)
|
||||
{
|
||||
MutexLockGuard guard(fullAccess);
|
||||
size_t pos;
|
||||
if (find(login, pos))
|
||||
{
|
||||
remove(pos);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InitInstance<FailedLogins> usernameFailedLogins;
|
||||
InitInstance<FailedLogins> remoteFailedLogins;
|
||||
}
|
||||
#endif //EMBEDDED
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Private interface
|
||||
@ -226,39 +206,35 @@ namespace {
|
||||
void SecurityDatabase::fini()
|
||||
{
|
||||
MutexLockGuard guard(mutex);
|
||||
if (--counter == 1)
|
||||
if (lookup_req)
|
||||
{
|
||||
if (lookup_req)
|
||||
{
|
||||
isc_release_request(status, &lookup_req);
|
||||
checkStatus("isc_release_request");
|
||||
}
|
||||
if (lookup_db)
|
||||
{
|
||||
isc_detach_database(status, &lookup_db);
|
||||
checkStatus("isc_detach_database");
|
||||
}
|
||||
isc_release_request(status, &lookup_req);
|
||||
checkStatus("isc_release_request");
|
||||
}
|
||||
if (lookup_db)
|
||||
{
|
||||
isc_detach_database(status, &lookup_db);
|
||||
checkStatus("isc_detach_database");
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityDatabase::init()
|
||||
{
|
||||
MutexLockGuard guard(mutex);
|
||||
++counter;
|
||||
if (! timer)
|
||||
{
|
||||
timer = fb_alloc_timer();
|
||||
getPath(user_info_name);
|
||||
}
|
||||
}
|
||||
|
||||
bool SecurityDatabase::lookup_user(const TEXT* user_name, int* uid, int* gid, TEXT* pwd)
|
||||
bool SecurityDatabase::lookup_user(const char* user_name, char* pwd)
|
||||
{
|
||||
bool found = false; // user found flag
|
||||
TEXT uname[129]; // user name buffer
|
||||
char uname[129]; // user name buffer
|
||||
user_record user; // user record
|
||||
|
||||
// Start by clearing the output data
|
||||
|
||||
if (uid)
|
||||
*uid = 0;
|
||||
if (gid)
|
||||
*gid = 0;
|
||||
if (pwd)
|
||||
*pwd = '\0';
|
||||
|
||||
@ -289,10 +265,6 @@ bool SecurityDatabase::lookup_user(const TEXT* user_name, int* uid, int* gid, TE
|
||||
if (!user.flag || status[1])
|
||||
break;
|
||||
found = true;
|
||||
if (uid)
|
||||
*uid = user.uid;
|
||||
if (gid)
|
||||
*gid = user.gid;
|
||||
if (pwd)
|
||||
{
|
||||
strncpy(pwd, user.password, MAX_PASSWORD_LENGTH);
|
||||
@ -303,22 +275,21 @@ bool SecurityDatabase::lookup_user(const TEXT* user_name, int* uid, int* gid, TE
|
||||
isc_rollback_transaction(status, &lookup_trans);
|
||||
checkStatus("isc_rollback_transaction");
|
||||
|
||||
fb_thread_timer(timer, 10000, Shutdown, 0);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
void SecurityDatabase::prepare()
|
||||
{
|
||||
TEXT user_info_name[MAXPATHLEN];
|
||||
|
||||
if (lookup_db)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lookup_db = lookup_req = 0;
|
||||
init();
|
||||
|
||||
// Initialize the database name
|
||||
getPath(user_info_name);
|
||||
lookup_db = lookup_req = 0;
|
||||
|
||||
// Perhaps build up a dpb
|
||||
ClumpletWriter dpb(ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1);
|
||||
@ -351,41 +322,9 @@ void SecurityDatabase::prepare()
|
||||
* Public interface
|
||||
*/
|
||||
|
||||
void SecurityDatabase::initialize()
|
||||
Result SecurityDatabase::verify(WriterInterface* authBlock,
|
||||
ClumpletReader& originalDpb)
|
||||
{
|
||||
instance.init();
|
||||
}
|
||||
|
||||
void SecurityDatabase::shutdown()
|
||||
{
|
||||
instance.fini();
|
||||
}
|
||||
|
||||
void SecurityDatabase::verifyUser(string& name,
|
||||
const TEXT* user_name,
|
||||
const TEXT* password,
|
||||
const TEXT* password_enc,
|
||||
int* uid,
|
||||
int* gid,
|
||||
int* node_id,
|
||||
const string& remoteId)
|
||||
{
|
||||
if (user_name)
|
||||
{
|
||||
name = user_name;
|
||||
for (unsigned int n = 0; n < name.length(); ++n)
|
||||
{
|
||||
name[n] = UPPER7(name[n]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef EMBEDDED
|
||||
else
|
||||
{
|
||||
remoteFailedLogins().loginFail(remoteId);
|
||||
status_exception::raise(Arg::Gds(isc_login));
|
||||
}
|
||||
|
||||
static AmCache useNative = AM_UNKNOWN;
|
||||
if (useNative == AM_UNKNOWN)
|
||||
{
|
||||
@ -396,65 +335,71 @@ void SecurityDatabase::verifyUser(string& name,
|
||||
}
|
||||
if (useNative == AM_DISABLED)
|
||||
{
|
||||
remoteFailedLogins().loginFail(remoteId);
|
||||
status_exception::raise(Arg::Gds(isc_login));
|
||||
return AUTH_CONTINUE;
|
||||
}
|
||||
|
||||
// Look up the user name in the userinfo database and use the parameters
|
||||
// found there. This means that another database must be accessed, and
|
||||
// that means the current context must be saved and restored.
|
||||
|
||||
TEXT pw1[MAX_PASSWORD_LENGTH + 1];
|
||||
const bool found = instance.lookup_user(name.c_str(), uid, gid, pw1);
|
||||
pw1[MAX_PASSWORD_LENGTH] = 0;
|
||||
string storedHash(pw1, MAX_PASSWORD_LENGTH);
|
||||
storedHash.rtrim();
|
||||
|
||||
// Punt if the user has specified neither a raw nor an encrypted password,
|
||||
// or if the user has specified both a raw and an encrypted password,
|
||||
// or if the user name specified was not in the password database
|
||||
// (or if there was no password database - it's still not found)
|
||||
|
||||
if ((!password && !password_enc) || (password && password_enc) || !found)
|
||||
string login, password, passwordEnc;
|
||||
for (originalDpb.rewind(); !originalDpb.isEof(); originalDpb.moveNext())
|
||||
{
|
||||
usernameFailedLogins().loginFail(name);
|
||||
remoteFailedLogins().loginFail(remoteId);
|
||||
status_exception::raise(Arg::Gds(isc_login));
|
||||
}
|
||||
|
||||
TEXT pwt[MAX_PASSWORD_LENGTH + 2];
|
||||
if (password)
|
||||
{
|
||||
ENC_crypt(pwt, sizeof pwt, password, PASSWORD_SALT);
|
||||
password_enc = pwt + 2;
|
||||
}
|
||||
|
||||
string newHash;
|
||||
hash(newHash, name, password_enc, storedHash);
|
||||
if (newHash != storedHash)
|
||||
{
|
||||
bool legacyHash = Config::getLegacyHash();
|
||||
if (legacyHash)
|
||||
switch (originalDpb.getClumpTag())
|
||||
{
|
||||
newHash.resize(MAX_PASSWORD_LENGTH + 2);
|
||||
ENC_crypt(newHash.begin(), newHash.length(), password_enc, PASSWORD_SALT);
|
||||
newHash.recalculate_length();
|
||||
newHash.erase(0, 2);
|
||||
legacyHash = newHash == storedHash;
|
||||
}
|
||||
if (! legacyHash)
|
||||
{
|
||||
usernameFailedLogins().loginFail(name);
|
||||
remoteFailedLogins().loginFail(remoteId);
|
||||
status_exception::raise(Arg::Gds(isc_login));
|
||||
case isc_dpb_user_name:
|
||||
originalDpb.getString(login);
|
||||
break;
|
||||
case isc_dpb_password:
|
||||
originalDpb.getString(password);
|
||||
break;
|
||||
case isc_dpb_password_enc:
|
||||
originalDpb.getString(passwordEnc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
usernameFailedLogins().loginSuccess(name);
|
||||
remoteFailedLogins().loginSuccess(remoteId);
|
||||
#endif
|
||||
if (login.hasData() && (password.hasData() || passwordEnc.hasData()))
|
||||
{
|
||||
login.upper();
|
||||
|
||||
*node_id = 0;
|
||||
// Look up the user name in the userinfo database and use the parameters
|
||||
// found there. This means that another database must be accessed, and
|
||||
// that means the current context must be saved and restored.
|
||||
|
||||
char pw1[MAX_PASSWORD_LENGTH + 1];
|
||||
const bool found = instance.lookup_user(login.c_str(), pw1);
|
||||
pw1[MAX_PASSWORD_LENGTH] = 0;
|
||||
string storedHash(pw1, MAX_PASSWORD_LENGTH);
|
||||
storedHash.rtrim();
|
||||
|
||||
if (!passwordEnc.hasData())
|
||||
{
|
||||
char pwt[MAX_PASSWORD_LENGTH + 2];
|
||||
ENC_crypt(pwt, sizeof pwt, password.c_str(), PASSWORD_SALT);
|
||||
passwordEnc.assign(&pwt[2]);
|
||||
}
|
||||
|
||||
string newHash;
|
||||
hash(newHash, login, passwordEnc, storedHash);
|
||||
if (newHash != storedHash)
|
||||
{
|
||||
bool legacyHash = Config::getLegacyHash();
|
||||
if (legacyHash)
|
||||
{
|
||||
newHash.resize(MAX_PASSWORD_LENGTH + 2);
|
||||
ENC_crypt(newHash.begin(), newHash.length(), passwordEnc.c_str(), PASSWORD_SALT);
|
||||
newHash.recalculate_length();
|
||||
newHash.erase(0, 2);
|
||||
legacyHash = newHash == storedHash;
|
||||
}
|
||||
if (! legacyHash)
|
||||
{
|
||||
return AUTH_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
authBlock->add(login.c_str(), "SecDB", instance.user_info_name);
|
||||
return AUTH_SUCCESS;
|
||||
}
|
||||
|
||||
return AUTH_CONTINUE;
|
||||
}
|
||||
|
||||
void SecurityDatabase::checkStatus(const char* callName, ISC_STATUS userError)
|
||||
@ -478,20 +423,51 @@ void SecurityDatabase::checkStatus(const char* callName, ISC_STATUS userError)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void DelayFailedLogin::raise(int sec)
|
||||
void SecurityDatabase::Shutdown(void*)
|
||||
{
|
||||
throw DelayFailedLogin(sec);
|
||||
instance.fini();
|
||||
}
|
||||
|
||||
ISC_STATUS DelayFailedLogin::stuff_exception(ISC_STATUS* const status_vector) const throw()
|
||||
ServerInstance* SecurityDatabaseServer::instance()
|
||||
{
|
||||
Arg::Gds(isc_login).copyTo(status_vector);
|
||||
|
||||
return status_vector[1];
|
||||
return interfaceAlloc<SecurityDatabaseServerInstance>();
|
||||
}
|
||||
|
||||
void DelayFailedLogin::sleep() const
|
||||
void SecurityDatabaseServer::getName(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
THREAD_SLEEP(1000 * seconds);
|
||||
const char* name = "LEGACY_AUTH";
|
||||
*data = (unsigned char*)name;
|
||||
*dataSize = strlen(name);
|
||||
}
|
||||
|
||||
void SecurityDatabaseServer::release()
|
||||
{
|
||||
gds__free(this);
|
||||
}
|
||||
|
||||
Result SecurityDatabaseServerInstance::startAuthentication(bool isService, const char*,
|
||||
const unsigned char* dpb, unsigned int dpbSize,
|
||||
WriterInterface* writerInterface)
|
||||
{
|
||||
ClumpletReader rdr(isService ? ClumpletReader::spbList : ClumpletReader::dpbList, dpb, dpbSize);
|
||||
return SecurityDatabase::verify(writerInterface, rdr);
|
||||
}
|
||||
|
||||
Result SecurityDatabaseServerInstance::contAuthentication(WriterInterface* writerInterface,
|
||||
const unsigned char* data, unsigned int size)
|
||||
{
|
||||
return AUTH_FAILED;
|
||||
}
|
||||
|
||||
void SecurityDatabaseServerInstance::getData(unsigned char** data, unsigned short* dataSize)
|
||||
{
|
||||
*data = NULL;
|
||||
*dataSize = 0;
|
||||
}
|
||||
|
||||
void SecurityDatabaseServerInstance::release()
|
||||
{
|
||||
gds__free(this);
|
||||
}
|
||||
|
||||
} // namespace Auth
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "../jrd/jrd.h"
|
||||
#include "../jrd/ods.h"
|
||||
#include "../jrd/scl.h"
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
#include "../jrd/acl.h"
|
||||
#include "../jrd/blb.h"
|
||||
#include "../jrd/irq.h"
|
||||
@ -1297,9 +1296,6 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
|
||||
break;
|
||||
|
||||
case id_node:
|
||||
if (check_hex(a, user.usr_node_id)) {
|
||||
hit = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -93,9 +93,7 @@ public:
|
||||
Firebird::string usr_org_name; // Organization name
|
||||
USHORT usr_user_id; // User id
|
||||
USHORT usr_group_id; // Group id
|
||||
USHORT usr_node_id; // Node id
|
||||
USHORT usr_flags; // Misc. crud
|
||||
//TEXT *usr_node_name; // Network node name
|
||||
|
||||
bool locksmith() const
|
||||
{
|
||||
@ -103,7 +101,7 @@ public:
|
||||
}
|
||||
|
||||
UserId()
|
||||
: usr_user_id(0), usr_group_id(0), usr_node_id(0), usr_flags(0)
|
||||
: usr_user_id(0), usr_group_id(0), usr_flags(0)
|
||||
{ }
|
||||
|
||||
UserId(Firebird::MemoryPool& p, const UserId& ui)
|
||||
@ -113,7 +111,6 @@ public:
|
||||
usr_org_name(p, ui.usr_org_name),
|
||||
usr_user_id(ui.usr_user_id),
|
||||
usr_group_id(ui.usr_group_id),
|
||||
usr_node_id(ui.usr_node_id),
|
||||
usr_flags(ui.usr_flags)
|
||||
{ }
|
||||
|
||||
@ -124,7 +121,6 @@ public:
|
||||
usr_org_name(ui.usr_org_name),
|
||||
usr_user_id(ui.usr_user_id),
|
||||
usr_group_id(ui.usr_group_id),
|
||||
usr_node_id(ui.usr_node_id),
|
||||
usr_flags(ui.usr_flags)
|
||||
{ }
|
||||
|
||||
@ -136,7 +132,6 @@ public:
|
||||
usr_org_name = ui.usr_org_name;
|
||||
usr_user_id = ui.usr_user_id;
|
||||
usr_group_id = ui.usr_group_id;
|
||||
usr_node_id = ui.usr_node_id;
|
||||
usr_flags = ui.usr_flags;
|
||||
|
||||
return *this;
|
||||
|
368
src/jrd/svc.cpp
368
src/jrd/svc.cpp
@ -146,133 +146,6 @@ namespace {
|
||||
Jrd::Service::StatusStringsHelper* strHelper;
|
||||
};
|
||||
|
||||
// Option block for service parameter block
|
||||
struct Options
|
||||
{
|
||||
string spb_sys_user_name;
|
||||
string spb_user_name;
|
||||
string spb_password;
|
||||
string spb_password_enc;
|
||||
string spb_command_line;
|
||||
string spb_network_protocol;
|
||||
string spb_remote_address;
|
||||
string spb_trusted_login;
|
||||
string spb_address_path;
|
||||
string spb_remote_process;
|
||||
SLONG spb_remote_pid;
|
||||
USHORT spb_version;
|
||||
bool spb_trusted_role;
|
||||
bool spb_remote;
|
||||
|
||||
// Parse service parameter block picking up options and things.
|
||||
explicit Options(ClumpletReader& spb) :
|
||||
spb_version(0),
|
||||
spb_trusted_role(false),
|
||||
spb_remote(false)
|
||||
{
|
||||
const UCHAR p = spb.getBufferTag();
|
||||
if (p != isc_spb_version1 && p != isc_spb_current_version)
|
||||
{
|
||||
ERR_post(Arg::Gds(isc_bad_spb_form) <<
|
||||
Arg::Gds(isc_wrospbver));
|
||||
}
|
||||
spb_version = p;
|
||||
|
||||
for (spb.rewind(); !(spb.isEof()); spb.moveNext())
|
||||
{
|
||||
switch (spb.getClumpTag())
|
||||
{
|
||||
case isc_spb_sys_user_name:
|
||||
spb.getString(spb_sys_user_name);
|
||||
break;
|
||||
|
||||
case isc_spb_user_name:
|
||||
spb.getString(spb_user_name);
|
||||
spb_user_name.upper();
|
||||
break;
|
||||
|
||||
case isc_spb_password:
|
||||
spb.getString(spb_password);
|
||||
break;
|
||||
|
||||
case isc_spb_password_enc:
|
||||
spb.getString(spb_password_enc);
|
||||
break;
|
||||
|
||||
case isc_spb_trusted_auth:
|
||||
spb.getString(spb_trusted_login);
|
||||
break;
|
||||
|
||||
case isc_spb_trusted_role:
|
||||
spb_trusted_role = true;
|
||||
break;
|
||||
|
||||
case isc_spb_command_line:
|
||||
spb.getString(spb_command_line);
|
||||
{
|
||||
// HACK: this does not care about the words on allowed places.
|
||||
string cLine = spb_command_line;
|
||||
cLine.upper();
|
||||
if (cLine.find(TRUSTED_USER_SWITCH) != string::npos ||
|
||||
cLine.find(TRUSTED_ROLE_SWITCH) != string::npos)
|
||||
{
|
||||
(Arg::Gds(isc_bad_spb_form) << Arg::Gds(isc_no_trusted_spb)).raise();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case isc_spb_address_path:
|
||||
spb.getString(spb_address_path);
|
||||
spb_remote = true;
|
||||
{
|
||||
ClumpletReader address_stack(ClumpletReader::UnTagged,
|
||||
spb.getBytes(), spb.getClumpLength());
|
||||
while (!address_stack.isEof())
|
||||
{
|
||||
if (address_stack.getClumpTag() != isc_dpb_address)
|
||||
{
|
||||
address_stack.moveNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
ClumpletReader address(ClumpletReader::UnTagged,
|
||||
address_stack.getBytes(), address_stack.getClumpLength());
|
||||
|
||||
while (!address.isEof())
|
||||
{
|
||||
switch (address.getClumpTag())
|
||||
{
|
||||
case isc_dpb_addr_protocol:
|
||||
address.getString(spb_network_protocol);
|
||||
break;
|
||||
case isc_dpb_addr_endpoint:
|
||||
address.getString(spb_remote_address);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
address.moveNext();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case isc_spb_process_name:
|
||||
spb.getString(spb_remote_process);
|
||||
break;
|
||||
|
||||
case isc_spb_process_id:
|
||||
spb_remote_pid = spb.getInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Generic mutex to synchronize services
|
||||
GlobalPtr<Mutex> globalServicesMutex;
|
||||
|
||||
@ -300,6 +173,13 @@ namespace {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void spbVersionError()
|
||||
{
|
||||
ERR_post(Arg::Gds(isc_bad_spb_form) <<
|
||||
Arg::Gds(isc_wrospbver));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
@ -345,6 +225,96 @@ void Service::ExistenceGuard::release()
|
||||
}
|
||||
}
|
||||
|
||||
void Service::getOptions(ClumpletReader& spb)
|
||||
{
|
||||
svc_spb_version = spb.getBufferTag();
|
||||
|
||||
for (spb.rewind(); !(spb.isEof()); spb.moveNext())
|
||||
{
|
||||
switch (spb.getClumpTag())
|
||||
{
|
||||
case isc_spb_user_name:
|
||||
spb.getString(svc_username);
|
||||
svc_username.upper();
|
||||
break;
|
||||
|
||||
case isc_spb_auth_block:
|
||||
svc_auth_block.clear();
|
||||
svc_auth_block.add(spb.getBytes(), spb.getClumpLength());
|
||||
break;
|
||||
|
||||
case isc_spb_trusted_auth:
|
||||
spb.getString(svc_trusted_login);
|
||||
break;
|
||||
|
||||
case isc_spb_trusted_role:
|
||||
svc_trusted_role = true;
|
||||
break;
|
||||
|
||||
case isc_spb_command_line:
|
||||
spb.getString(svc_command_line);
|
||||
{
|
||||
// HACK: this does not care about the words on allowed places.
|
||||
string cLine = svc_command_line;
|
||||
cLine.upper();
|
||||
if (cLine.find(TRUSTED_USER_SWITCH) != string::npos ||
|
||||
cLine.find(TRUSTED_ROLE_SWITCH) != string::npos)
|
||||
{
|
||||
(Arg::Gds(isc_bad_spb_form) << Arg::Gds(isc_no_trusted_spb)).raise();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case isc_spb_address_path:
|
||||
spb.getString(svc_address_path);
|
||||
{
|
||||
ClumpletReader address_stack(ClumpletReader::UnTagged,
|
||||
spb.getBytes(), spb.getClumpLength());
|
||||
while (!address_stack.isEof())
|
||||
{
|
||||
if (address_stack.getClumpTag() != isc_dpb_address)
|
||||
{
|
||||
address_stack.moveNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
ClumpletReader address(ClumpletReader::UnTagged,
|
||||
address_stack.getBytes(), address_stack.getClumpLength());
|
||||
|
||||
while (!address.isEof())
|
||||
{
|
||||
switch (address.getClumpTag())
|
||||
{
|
||||
case isc_dpb_addr_protocol:
|
||||
address.getString(svc_network_protocol);
|
||||
break;
|
||||
case isc_dpb_addr_endpoint:
|
||||
address.getString(svc_remote_address);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
address.moveNext();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case isc_spb_process_name:
|
||||
spb.getString(svc_remote_process);
|
||||
break;
|
||||
|
||||
case isc_spb_process_id:
|
||||
svc_remote_pid = spb.getInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Service::parseSwitches()
|
||||
{
|
||||
svc_parsed_sw = svc_switches;
|
||||
@ -776,9 +746,10 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
|
||||
svc_stdout_head(0), svc_stdout_tail(0), svc_service(NULL), svc_service_run(NULL),
|
||||
svc_resp_alloc(getPool()), svc_resp_buf(0), svc_resp_ptr(0), svc_resp_buf_len(0),
|
||||
svc_resp_len(0), svc_flags(0), svc_user_flag(0), svc_spb_version(0), svc_do_shutdown(false),
|
||||
svc_username(getPool()), svc_enc_password(getPool()),
|
||||
svc_trusted_login(getPool()), svc_trusted_role(false), svc_uses_security_database(false),
|
||||
svc_username(getPool()), svc_auth_block(getPool()),
|
||||
svc_trusted_login(getPool()), svc_trusted_role(false),
|
||||
svc_switches(getPool()), svc_perm_sw(getPool()), svc_address_path(getPool()),
|
||||
svc_command_line(getPool()),
|
||||
svc_network_protocol(getPool()), svc_remote_address(getPool()), svc_remote_process(getPool()),
|
||||
svc_remote_pid(0), svc_current_guard(NULL)
|
||||
{
|
||||
@ -818,72 +789,65 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
|
||||
}
|
||||
|
||||
// Process the service parameter block.
|
||||
ClumpletReader spb(ClumpletReader::SpbAttach, spb_data, spb_length);
|
||||
Options options(spb);
|
||||
ClumpletReader spb(ClumpletReader::spbList, spb_data, spb_length, spbVersionError);
|
||||
getOptions(spb);
|
||||
|
||||
// Perhaps checkout the user in the security database.
|
||||
SecurityDatabase::InitHolder siHolder;
|
||||
USHORT user_flag;
|
||||
if (!strcmp(serv->serv_name, "anonymous")) {
|
||||
user_flag = SVC_user_none;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we have embedded service connection, let's check for unix OS auth
|
||||
if (!options.spb_trusted_login.hasData() && !options.spb_remote &&
|
||||
!options.spb_user_name.hasData())
|
||||
if (svc_trusted_login.hasData())
|
||||
{
|
||||
if (ISC_get_user(&options.spb_trusted_login, NULL, NULL, NULL)) {
|
||||
options.spb_trusted_login = SYSDBA_USER_NAME;
|
||||
}
|
||||
svc_username = svc_trusted_login;
|
||||
}
|
||||
|
||||
if (options.spb_trusted_login.hasData()) {
|
||||
options.spb_user_name = options.spb_trusted_login;
|
||||
}
|
||||
else
|
||||
if (!svc_username.hasData())
|
||||
{
|
||||
// If we have embedded service connection, let's check for environment
|
||||
if (!options.spb_remote)
|
||||
if (svc_auth_block.hasData())
|
||||
{
|
||||
if (!options.spb_user_name.hasData()) {
|
||||
fb_utils::readenv(ISC_USER, options.spb_user_name);
|
||||
}
|
||||
if (!options.spb_password.hasData()) {
|
||||
fb_utils::readenv(ISC_PASSWORD, options.spb_password);
|
||||
// stub instead mapUser(....);
|
||||
AuthReader auth(svc_auth_block);
|
||||
Firebird::string method;
|
||||
if (auth.getInfo(&svc_username, &method) && method == "WIN_SSPI")
|
||||
{
|
||||
auth.moveNext();
|
||||
if (!auth.isEof())
|
||||
{
|
||||
svc_trusted_role = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.spb_user_name.hasData())
|
||||
else
|
||||
{
|
||||
// user name and password are required while
|
||||
// attaching to the services manager
|
||||
status_exception::raise(Arg::Gds(isc_service_att_err) << Arg::Gds(isc_svcnouser));
|
||||
// we have embedded service connection, check environment and unix OS auth
|
||||
if (!fb_utils::readenv(ISC_USER, svc_username))
|
||||
{
|
||||
if (ISC_get_user(&svc_username, NULL, NULL, NULL))
|
||||
{
|
||||
svc_username = SYSDBA_USER_NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string name; // unused after retrieved
|
||||
int id, group, node_id;
|
||||
|
||||
const string remote = options.spb_network_protocol +
|
||||
(options.spb_network_protocol.isEmpty() ||
|
||||
options.spb_remote_address.isEmpty() ? "" : "/") +
|
||||
options.spb_remote_address;
|
||||
|
||||
SecurityDatabase::verifyUser(name, options.spb_user_name.nullStr(),
|
||||
options.spb_password.nullStr(),
|
||||
options.spb_password_enc.nullStr(),
|
||||
&id, &group, &node_id, remote);
|
||||
svc_uses_security_database = true;
|
||||
}
|
||||
|
||||
if (options.spb_user_name.length() > USERNAME_LENGTH)
|
||||
if (!svc_username.hasData())
|
||||
{
|
||||
// user name and password are required while
|
||||
// attaching to the services manager
|
||||
status_exception::raise(Arg::Gds(isc_service_att_err) << Arg::Gds(isc_svcnouser));
|
||||
}
|
||||
|
||||
if (svc_username.length() > USERNAME_LENGTH)
|
||||
{
|
||||
status_exception::raise(Arg::Gds(isc_long_login) <<
|
||||
Arg::Num(options.spb_user_name.length()) << Arg::Num(USERNAME_LENGTH));
|
||||
Arg::Num(svc_username.length()) << Arg::Num(USERNAME_LENGTH));
|
||||
}
|
||||
|
||||
// Check that the validated user has the authority to access this service
|
||||
if (options.spb_user_name != SYSDBA_USER_NAME && !options.spb_trusted_role) {
|
||||
if (svc_username != SYSDBA_USER_NAME && !svc_trusted_role) {
|
||||
user_flag = SVC_user_any;
|
||||
}
|
||||
else {
|
||||
@ -895,53 +859,23 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
|
||||
string switches;
|
||||
if (serv->serv_std_switches)
|
||||
switches = serv->serv_std_switches;
|
||||
if (options.spb_command_line.hasData() && serv->serv_std_switches)
|
||||
if (svc_command_line.hasData() && serv->serv_std_switches)
|
||||
switches += ' ';
|
||||
switches += options.spb_command_line;
|
||||
switches += svc_command_line;
|
||||
|
||||
svc_flags = switches.hasData() ? SVC_cmd_line : 0;
|
||||
svc_perm_sw = switches;
|
||||
svc_user_flag = user_flag;
|
||||
svc_service = serv;
|
||||
svc_spb_version = options.spb_version;
|
||||
svc_username = options.spb_user_name;
|
||||
svc_trusted_login = options.spb_trusted_login;
|
||||
svc_trusted_role = options.spb_trusted_role;
|
||||
svc_address_path = options.spb_address_path;
|
||||
svc_network_protocol = options.spb_network_protocol;
|
||||
svc_remote_address = options.spb_remote_address;
|
||||
svc_remote_process = options.spb_remote_process;
|
||||
svc_remote_pid = options.spb_remote_pid;
|
||||
svc_trace_manager = FB_NEW(*getDefaultMemoryPool()) TraceManager(this);
|
||||
|
||||
// The password will be issued to the service threads on NT since
|
||||
// there is no OS authentication. If the password is not yet
|
||||
// encrypted, then encrypt it before saving it (since there is no
|
||||
// decrypt function).
|
||||
if (options.spb_password_enc.hasData())
|
||||
{
|
||||
svc_enc_password = options.spb_password_enc;
|
||||
}
|
||||
else if (options.spb_password.hasData())
|
||||
{
|
||||
svc_enc_password.resize(MAX_PASSWORD_LENGTH + 2);
|
||||
ENC_crypt(svc_enc_password.begin(), svc_enc_password.length(),
|
||||
options.spb_password.c_str(), PASSWORD_SALT);
|
||||
svc_enc_password.recalculate_length();
|
||||
svc_enc_password.erase(0, 2);
|
||||
}
|
||||
svc_trace_manager = FB_NEW(*getDefaultMemoryPool()) TraceManager(this);
|
||||
|
||||
// If an executable is defined for the service, try to fork a new thread.
|
||||
// Only do this if we are working with a version 1 service
|
||||
if (serv->serv_thd && options.spb_version == isc_spb_version1)
|
||||
if (serv->serv_thd && svc_spb_version == isc_spb_version1)
|
||||
{
|
||||
start(serv->serv_thd);
|
||||
}
|
||||
|
||||
if (svc_uses_security_database)
|
||||
{
|
||||
siHolder.clear();
|
||||
}
|
||||
} // try
|
||||
catch (const Firebird::Exception& ex)
|
||||
{
|
||||
@ -1004,11 +938,6 @@ void Service::detach()
|
||||
// save it cause after call to finish() we can't access class members any more
|
||||
const bool localDoShutdown = svc_do_shutdown;
|
||||
|
||||
if (svc_uses_security_database)
|
||||
{
|
||||
SecurityDatabase::shutdown();
|
||||
}
|
||||
|
||||
TraceServiceImpl service(this);
|
||||
svc_trace_manager->event_service_detach(&service, res_successful);
|
||||
|
||||
@ -1433,7 +1362,7 @@ ISC_STATUS Service::query2(thread_db* tdbb,
|
||||
{
|
||||
// The path to the user security database (security2.fdb)
|
||||
char* pb = reinterpret_cast<char*>(buffer);
|
||||
SecurityDatabase::getPath(pb);
|
||||
Auth::SecurityDatabase::getPath(pb);
|
||||
|
||||
if (!(info = INF_put_item(item, strlen(pb), buffer, info, end)))
|
||||
{
|
||||
@ -1858,7 +1787,7 @@ void Service::query(USHORT send_item_length,
|
||||
{
|
||||
// The path to the user security database (security2.fdb)
|
||||
char* pb = reinterpret_cast<char*>(buffer);
|
||||
SecurityDatabase::getPath(pb);
|
||||
Auth::SecurityDatabase::getPath(pb);
|
||||
|
||||
if (!(info = INF_put_item(item, strlen(pb), buffer, info, end)))
|
||||
{
|
||||
@ -2086,7 +2015,7 @@ void Service::start(USHORT spb_length, const UCHAR* spb_data)
|
||||
// add the username and password to the end of svc_switches if needed
|
||||
if (svc_switches.hasData())
|
||||
{
|
||||
if (svc_trusted_login.hasData())
|
||||
if (svc_username.hasData())
|
||||
{
|
||||
string auth = "-";
|
||||
auth += TRUSTED_USER_SWITCH;
|
||||
@ -2101,19 +2030,6 @@ void Service::start(USHORT spb_length, const UCHAR* spb_data)
|
||||
}
|
||||
svc_switches = auth + svc_switches;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No need repeating user validation in service worker thread
|
||||
if (svc_username.hasData())
|
||||
{
|
||||
string auth = "-";
|
||||
auth += TRUSTED_USER_SWITCH;
|
||||
auth += ' ';
|
||||
auth += svc_username;
|
||||
auth += ' ';
|
||||
svc_switches = auth + svc_switches;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
|
||||
#include "fb_blk.h"
|
||||
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
#include "../jrd/svc_undoc.h"
|
||||
#include "../jrd/ThreadStart.h"
|
||||
|
||||
@ -37,11 +36,11 @@
|
||||
#include "../common/classes/SafeArg.h"
|
||||
#include "../common/UtilSvc.h"
|
||||
#include "../common/classes/Switches.h"
|
||||
#include "../common/classes/ClumpletReader.h"
|
||||
|
||||
// forward decl.
|
||||
struct serv_entry;
|
||||
namespace Firebird {
|
||||
class ClumpletReader;
|
||||
namespace Arg {
|
||||
class StatusVector;
|
||||
}
|
||||
@ -169,9 +168,6 @@ public: // external interface with service
|
||||
|
||||
const Firebird::string& getUserName() const
|
||||
{
|
||||
if (svc_username.empty())
|
||||
return svc_trusted_login;
|
||||
|
||||
return svc_username;
|
||||
}
|
||||
|
||||
@ -239,6 +235,8 @@ private:
|
||||
static bool ck_space_for_numeric(UCHAR*& info, const UCHAR* const end);
|
||||
// Make status vector permamnent, if one present in worker thread's space
|
||||
void makePermanentStatusVector() throw();
|
||||
// Read SPB on attach
|
||||
void getOptions(Firebird::ClumpletReader&);
|
||||
|
||||
private:
|
||||
ISC_STATUS_ARRAY svc_status; // status vector for running service
|
||||
@ -260,13 +258,14 @@ private:
|
||||
bool svc_do_shutdown;
|
||||
|
||||
Firebird::string svc_username;
|
||||
Firebird::string svc_enc_password;
|
||||
Firebird::AuthReader::AuthBlock svc_auth_block;
|
||||
Firebird::string svc_trusted_login;
|
||||
bool svc_trusted_role;
|
||||
bool svc_uses_security_database;
|
||||
Firebird::string svc_switches; // Full set of switches
|
||||
Firebird::string svc_perm_sw; // Switches, taken from services table and/or passed using spb_command_line
|
||||
Firebird::string svc_address_path;
|
||||
Firebird::string svc_command_line;
|
||||
|
||||
Firebird::string svc_network_protocol;
|
||||
Firebird::string svc_remote_address;
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include "../jrd/extds/ExtDS.h"
|
||||
#include "../jrd/rse.h"
|
||||
#include "../jrd/intl_classes.h"
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
#include "../jrd/ThreadStart.h"
|
||||
#include "../jrd/UserManagement.h"
|
||||
#include "../jrd/blb_proto.h"
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "../../jrd/isc_proto.h"
|
||||
#include "../../jrd/isc_s_proto.h"
|
||||
#include "../../jrd/jrd.h"
|
||||
#include "../../jrd/jrd_pwd.h"
|
||||
#include "../../jrd/tra.h"
|
||||
#include "../../jrd/evl_proto.h"
|
||||
#include "../../jrd/mov_proto.h"
|
||||
|
@ -424,10 +424,6 @@ rem_port* INET_analyze(const Firebird::PathName& file_name,
|
||||
}
|
||||
|
||||
// Establish connection to server
|
||||
|
||||
// Note: prior to V3.1E a recievers could not in truth handle more
|
||||
// than 5 protocol descriptions, so we try them in chunks of 5 or less
|
||||
|
||||
// If we want user verification, we can't speak anything less than version 7
|
||||
|
||||
P_CNCT* cnct = &packet->p_cnct;
|
||||
@ -440,7 +436,8 @@ rem_port* INET_analyze(const Firebird::PathName& file_name,
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, MAX_PTYPE, 1),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, MAX_PTYPE, 2),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION11, ptype_rpc, MAX_PTYPE, 3),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION12, ptype_rpc, MAX_PTYPE, 4)
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION12, ptype_rpc, MAX_PTYPE, 4),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION13, ptype_rpc, MAX_PTYPE, 5)
|
||||
};
|
||||
|
||||
cnct->p_cnct_count = FB_NELEM(protocols_to_try1);
|
||||
@ -479,31 +476,6 @@ rem_port* INET_analyze(const Firebird::PathName& file_name,
|
||||
}
|
||||
}
|
||||
|
||||
if (packet->p_operation == op_reject && !uv_flag)
|
||||
{
|
||||
disconnect(port);
|
||||
|
||||
// try again with next set of known protocols
|
||||
|
||||
cnct->p_cnct_user_id.cstr_length = (USHORT) user_id.getBufferLength();
|
||||
cnct->p_cnct_user_id.cstr_address = user_id.getBuffer();
|
||||
|
||||
static const p_cnct::p_cnct_repeat protocols_to_try3[] =
|
||||
{
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION3, ptype_rpc, ptype_batch_send, 1),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION4, ptype_rpc, ptype_batch_send, 2)
|
||||
};
|
||||
|
||||
cnct->p_cnct_count = FB_NELEM(protocols_to_try3);
|
||||
|
||||
copy_p_cnct_repeat_array(cnct->p_cnct_versions, protocols_to_try3, cnct->p_cnct_count);
|
||||
|
||||
port = inet_try_connect(packet, rdb, file_name, node_name, status_vector, dpb);
|
||||
if (!port) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (packet->p_operation != op_accept)
|
||||
{
|
||||
*status_vector++ = isc_arg_gds;
|
||||
|
@ -431,7 +431,7 @@ int FB_EXPORTED server_main( int argc, char** argv)
|
||||
ISC_STATUS_ARRAY status;
|
||||
isc_db_handle db_handle = 0L;
|
||||
|
||||
Jrd::SecurityDatabase::getPath(path);
|
||||
Auth::SecurityDatabase::getPath(path);
|
||||
const char dpb[] = {isc_dpb_version1, isc_dpb_gsec_attach, 1, 1};
|
||||
isc_attach_database(status, strlen(path), path, &db_handle, sizeof dpb, dpb);
|
||||
if (status[0] == 1 && status[1] > 0)
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include "../jrd/license.h"
|
||||
#include "../jrd/fil.h"
|
||||
#include "../jrd/sdl.h"
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
#include "../remote/inet_proto.h"
|
||||
#include "../remote/inter_proto.h"
|
||||
#include "../remote/merge_proto.h"
|
||||
@ -60,11 +59,14 @@
|
||||
#include "../jrd/gds_proto.h"
|
||||
#include "../jrd/isc_f_proto.h"
|
||||
#include "../jrd/sdl_proto.h"
|
||||
#include "../jrd/jrd_pwd.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../auth/trusted/AuthSspi.h"
|
||||
#include "../common/classes/DbImplementation.h"
|
||||
#include "../auth/Auth.h"
|
||||
#include "../auth/SecurityDatabase/LegacyClient.h"
|
||||
#include "../auth/trusted/AuthSspi.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -96,8 +98,7 @@ namespace {
|
||||
struct ParametersSet
|
||||
{
|
||||
UCHAR dummy_packet_interval, user_name, sys_user_name,
|
||||
password, password_enc, address_path, process_id, process_name,
|
||||
trusted_auth, trusted_role;
|
||||
password, password_enc, address_path, process_id, process_name;
|
||||
};
|
||||
const ParametersSet dpbParam = {isc_dpb_dummy_packet_interval,
|
||||
isc_dpb_user_name,
|
||||
@ -106,9 +107,7 @@ namespace {
|
||||
isc_dpb_password_enc,
|
||||
isc_dpb_address_path,
|
||||
isc_dpb_process_id,
|
||||
isc_dpb_process_name,
|
||||
isc_dpb_trusted_auth,
|
||||
isc_dpb_trusted_role};
|
||||
isc_dpb_process_name};
|
||||
const ParametersSet spbParam = {isc_spb_dummy_packet_interval,
|
||||
isc_spb_user_name,
|
||||
isc_spb_sys_user_name,
|
||||
@ -116,9 +115,7 @@ namespace {
|
||||
isc_spb_password_enc,
|
||||
isc_spb_address_path,
|
||||
isc_spb_process_id,
|
||||
isc_spb_process_name,
|
||||
isc_spb_trusted_auth,
|
||||
isc_spb_trusted_role};
|
||||
isc_spb_process_name};
|
||||
}
|
||||
|
||||
static Rvnt* add_event(rem_port*);
|
||||
@ -144,7 +141,7 @@ static bool get_single_user(ClumpletReader&);
|
||||
static ISC_STATUS handle_error(ISC_STATUS *, ISC_STATUS);
|
||||
static ISC_STATUS info(ISC_STATUS*, Rdb*, P_OP, USHORT, USHORT, USHORT,
|
||||
const UCHAR*, USHORT, const UCHAR*, USHORT, UCHAR*);
|
||||
static bool init(ISC_STATUS *, rem_port*, P_OP, PathName&, ClumpletWriter&, const ParametersSet&);
|
||||
static bool init(ISC_STATUS *, rem_port*, P_OP, PathName&, ClumpletWriter&);
|
||||
static Rtr* make_transaction(Rdb*, USHORT);
|
||||
static bool mov_dsql_message(ISC_STATUS*, const UCHAR*, const rem_fmt*, UCHAR*, const rem_fmt*);
|
||||
static void move_error(const Arg::StatusVector& v);
|
||||
@ -320,7 +317,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
add_other_params(port, newDpb, dpbParam);
|
||||
add_working_directory(newDpb, node_name);
|
||||
|
||||
const bool result = init(user_status, port, op_attach, expanded_name, newDpb, dpbParam);
|
||||
const bool result = init(user_status, port, op_attach, expanded_name, newDpb);
|
||||
|
||||
if (!result) {
|
||||
return user_status[1];
|
||||
@ -846,7 +843,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
add_other_params(port, newDpb, dpbParam);
|
||||
add_working_directory(newDpb, node_name);
|
||||
|
||||
const bool result = init(user_status, port, op_create, expanded_name, newDpb, dpbParam);
|
||||
const bool result = init(user_status, port, op_create, expanded_name, newDpb);
|
||||
if (!result) {
|
||||
return user_status[1];
|
||||
}
|
||||
@ -3798,8 +3795,8 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status,
|
||||
Rdb* rdb = 0;
|
||||
|
||||
try {
|
||||
ClumpletWriter newSpb(ClumpletReader::SpbAttach, MAX_DPB_SIZE,
|
||||
reinterpret_cast<const UCHAR*>(spb), spb_length, isc_spb_current_version);
|
||||
ClumpletWriter newSpb(ClumpletReader::spbList, MAX_DPB_SIZE,
|
||||
reinterpret_cast<const UCHAR*>(spb), spb_length);
|
||||
string user_string;
|
||||
|
||||
const bool user_verification = get_new_dpb(newSpb, user_string, spbParam);
|
||||
@ -3827,7 +3824,7 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status,
|
||||
|
||||
add_other_params(port, newSpb, spbParam);
|
||||
|
||||
const bool result = init(user_status, port, op_service_attach, expanded_name, newSpb, spbParam);
|
||||
const bool result = init(user_status, port, op_service_attach, expanded_name, newSpb);
|
||||
if (!result) {
|
||||
return user_status[1];
|
||||
}
|
||||
@ -5425,8 +5422,8 @@ static bool get_new_dpb(ClumpletWriter& dpb, string& user_string, const Paramete
|
||||
ISC_systemToUtf8(password);
|
||||
ISC_unescape(password);
|
||||
|
||||
TEXT pwt[MAX_PASSWORD_LENGTH + 2];
|
||||
ENC_crypt(pwt, sizeof pwt, password.c_str(), PASSWORD_SALT);
|
||||
TEXT pwt[Auth::MAX_PASSWORD_LENGTH + 2];
|
||||
ENC_crypt(pwt, sizeof pwt, password.c_str(), Auth::PASSWORD_SALT);
|
||||
password = pwt + 2;
|
||||
dpb.insertString(par.password_enc, password);
|
||||
}
|
||||
@ -5561,12 +5558,39 @@ static ISC_STATUS info(ISC_STATUS* user_status,
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
class InitList
|
||||
{
|
||||
public:
|
||||
typedef Firebird::HalfStaticArray<Auth::ClientPlugin*, 8> List;
|
||||
static List* init()
|
||||
{
|
||||
List* list = FB_NEW(*getDefaultMemoryPool()) List(*getDefaultMemoryPool());
|
||||
|
||||
// this code will be replaced with known plugins scan
|
||||
list->push(Auth::interfaceAlloc<Auth::SecurityDatabaseClient>());
|
||||
#ifdef TRUSTED_AUTH
|
||||
list->push(Auth::interfaceAlloc<Auth::WinSspiClient>());
|
||||
#endif
|
||||
#ifdef AUTH_DEBUG
|
||||
list->push(Auth::interfaceAlloc<Auth::DebugClient>());
|
||||
#endif
|
||||
|
||||
// must be last
|
||||
list->push(NULL);
|
||||
return list;
|
||||
}
|
||||
};
|
||||
|
||||
Firebird::InitInstance<InitList::List, InitList> listArray;
|
||||
}
|
||||
|
||||
|
||||
static bool init(ISC_STATUS* user_status,
|
||||
rem_port* port,
|
||||
P_OP op,
|
||||
PathName& file_name,
|
||||
ClumpletWriter& dpb,
|
||||
const ParametersSet& param)
|
||||
ClumpletWriter& dpb)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -5585,25 +5609,32 @@ static bool init(ISC_STATUS* user_status,
|
||||
MemoryPool& pool = *getDefaultMemoryPool();
|
||||
port->port_deferred_packets = FB_NEW(pool) PacketQueue(pool);
|
||||
|
||||
// Do we can & need to try trusted auth
|
||||
// Let plugins try to add data to DPB in order to avoid extra network roundtrip
|
||||
AutoPtr<Auth::ClientInstance, Auth::Auto> currentInstance;
|
||||
Auth::DpbImplementation di(dpb);
|
||||
unsigned int sequence = 0;
|
||||
Auth::ClientPlugin** list = listArray().begin();
|
||||
|
||||
dpb.deleteWithTag(param.trusted_auth);
|
||||
dpb.deleteWithTag(param.trusted_role);
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
AuthSspi authSspi;
|
||||
AuthSspi::DataHolder data;
|
||||
|
||||
if ((port->port_protocol >= PROTOCOL_VERSION11) &&
|
||||
((!dpb.find(param.user_name)) || (dpb.getClumpLength() == 0)))
|
||||
for (bool working = true; working && list[sequence]; ++sequence)
|
||||
{
|
||||
if (authSspi.request(data))
|
||||
if (port->port_protocol >= PROTOCOL_VERSION13 ||
|
||||
(port->port_protocol >= PROTOCOL_VERSION11 && Auth::legacy(list[sequence])))
|
||||
{
|
||||
// on no error we send data no matter, was context created or not
|
||||
dpb.insertBytes(param.trusted_auth, data.begin(), data.getCount());
|
||||
// plugin may be used
|
||||
currentInstance.reset(list[sequence]->instance());
|
||||
switch(currentInstance->startAuthentication(op == op_service_attach, file_name.c_str(), &di))
|
||||
{
|
||||
case Auth::AUTH_SUCCESS:
|
||||
working = false;
|
||||
break;
|
||||
case Auth::AUTH_FAILED:
|
||||
disconnect(port);
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //TRUSTED_AUTH
|
||||
|
||||
if (port->port_protocol < PROTOCOL_VERSION12)
|
||||
{
|
||||
@ -5642,7 +5673,6 @@ static bool init(ISC_STATUS* user_status,
|
||||
}
|
||||
|
||||
// Make attach packet
|
||||
|
||||
P_ATCH* attach = &packet->p_atch;
|
||||
packet->p_operation = op;
|
||||
attach->p_atch_file.cstr_length = file_name.length();
|
||||
@ -5656,62 +5686,107 @@ static bool init(ISC_STATUS* user_status,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get response
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
ISC_STATUS* status = packet->p_resp.p_resp_status_vector = rdb->rdb_status_vector;
|
||||
if (!receive_packet(rdb->rdb_port, packet, status))
|
||||
for (;;)
|
||||
{
|
||||
REMOTE_save_status_strings(user_status);
|
||||
disconnect(port);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (packet->p_operation == op_trusted_auth)
|
||||
{
|
||||
if (!authSspi.isActive())
|
||||
{
|
||||
disconnect(port);
|
||||
return false; // isc_unavailable
|
||||
}
|
||||
cstring* d = &packet->p_trau.p_trau_data;
|
||||
memcpy(data.getBuffer(d->cstr_length), d->cstr_address, d->cstr_length);
|
||||
REMOTE_free_packet(rdb->rdb_port, packet);
|
||||
if (!authSspi.request(data))
|
||||
{
|
||||
disconnect(port);
|
||||
return false; // isc_unavailable
|
||||
}
|
||||
packet->p_operation = op_trusted_auth;
|
||||
d->cstr_address = data.begin();
|
||||
d->cstr_length = data.getCount();
|
||||
|
||||
if (!send_packet(rdb->rdb_port, packet, user_status))
|
||||
{
|
||||
disconnect(port);
|
||||
return false;
|
||||
}
|
||||
// Get response
|
||||
ISC_STATUS* status = packet->p_resp.p_resp_status_vector = rdb->rdb_status_vector;
|
||||
if (!receive_packet(rdb->rdb_port, packet, status))
|
||||
{
|
||||
REMOTE_save_status_strings(user_status);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check response
|
||||
cstring* n = 0;
|
||||
cstring* d = 0;
|
||||
switch(packet->p_operation)
|
||||
{
|
||||
case op_trusted_auth:
|
||||
d = &packet->p_trau.p_trau_data;
|
||||
break;
|
||||
|
||||
case op_cont_auth:
|
||||
d = &packet->p_auth_cont.p_data;
|
||||
n = &packet->p_auth_cont.p_name;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (check_response(rdb, packet))
|
||||
{
|
||||
// successfully attached
|
||||
rdb->rdb_id = packet->p_resp.p_resp_object;
|
||||
return true;
|
||||
}
|
||||
|
||||
REMOTE_save_status_strings(user_status);
|
||||
disconnect(port);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool contFlag = true;
|
||||
if (n && n->cstr_length)
|
||||
{
|
||||
// switch to other plugin
|
||||
currentInstance.reset(0);
|
||||
|
||||
for (sequence = 0; list[sequence]; ++sequence)
|
||||
{
|
||||
UCHAR* nm;
|
||||
USHORT len;
|
||||
list[sequence]->getName(&nm, &len);
|
||||
if (len == n->cstr_length && memcmp(nm, n->cstr_address, len) == 0)
|
||||
{
|
||||
currentInstance.reset(list[sequence]->instance());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentInstance)
|
||||
{
|
||||
Auth::Result rc = currentInstance->startAuthentication(op == op_service_attach,
|
||||
file_name.c_str(), 0);
|
||||
if (rc == Auth::AUTH_FAILED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (rc != Auth::AUTH_MORE_DATA)
|
||||
{
|
||||
contFlag = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
contFlag = false;
|
||||
packet->p_trau.p_trau_data.cstr_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (contFlag)
|
||||
{
|
||||
// continue auth
|
||||
if (!currentInstance)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (currentInstance->contAuthentication(d->cstr_address, d->cstr_length) == Auth::AUTH_FAILED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// send answer (may be empty) to server
|
||||
packet->p_operation = op_trusted_auth;
|
||||
d = &packet->p_trau.p_trau_data;
|
||||
currentInstance->getData(&d->cstr_address, &d->cstr_length);
|
||||
|
||||
if (!send_packet(rdb->rdb_port, packet, user_status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_response(rdb, packet))
|
||||
#else // TRUSTED_AUTH
|
||||
if (!receive_response(rdb, packet))
|
||||
#endif //TRUSTED_AUTH
|
||||
{
|
||||
REMOTE_save_status_strings(user_status);
|
||||
disconnect(port);
|
||||
return false;
|
||||
}
|
||||
|
||||
rdb->rdb_id = packet->p_resp.p_resp_object;
|
||||
|
||||
return true;
|
||||
disconnect(port);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -166,10 +166,6 @@ rem_port* WNET_analyze(const Firebird::PathName& file_name,
|
||||
cnct->p_cnct_file.cstr_length = (USHORT) file_name.length();
|
||||
cnct->p_cnct_file.cstr_address = reinterpret_cast<const UCHAR*>(file_name.c_str());
|
||||
|
||||
// Note: prior to V3.1E a receivers could not in truth handle more
|
||||
// than 5 protocol descriptions; however, this restriction does not
|
||||
// apply to Windows since it was created in 4.0
|
||||
|
||||
// If we want user verification, we can't speak anything less than version 7
|
||||
|
||||
cnct->p_cnct_user_id.cstr_length = (USHORT) user_id.getBufferLength();
|
||||
@ -181,7 +177,8 @@ rem_port* WNET_analyze(const Firebird::PathName& file_name,
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, ptype_batch_send, 2),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, ptype_batch_send, 3),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION11, ptype_rpc, ptype_batch_send, 4),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION12, ptype_rpc, ptype_batch_send, 5)
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION12, ptype_rpc, ptype_batch_send, 5),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION13, ptype_rpc, ptype_batch_send, 6)
|
||||
};
|
||||
cnct->p_cnct_count = FB_NELEM(protocols_to_try1);
|
||||
|
||||
|
@ -747,6 +747,16 @@ bool_t xdr_protocol(XDR* xdrs, PACKET* p)
|
||||
return P_TRUE(xdrs, p);
|
||||
}
|
||||
|
||||
case op_cont_auth:
|
||||
{
|
||||
P_AUTH_CONT* auth = &p->p_auth_cont;
|
||||
MAP(xdr_cstring, auth->p_data);
|
||||
MAP(xdr_cstring, auth->p_name);
|
||||
DEBUG_PRINTSIZE(xdrs, p->p_operation);
|
||||
|
||||
return P_TRUE(xdrs, p);
|
||||
}
|
||||
|
||||
case op_cancel:
|
||||
{
|
||||
P_CANCEL_OP* cancel_op = &p->p_cancel_op;
|
||||
|
@ -99,6 +99,10 @@ const USHORT PROTOCOL_VERSION11 = (FB_PROTOCOL_FLAG | 11);
|
||||
|
||||
const USHORT PROTOCOL_VERSION12 = (FB_PROTOCOL_FLAG | 12);
|
||||
|
||||
// Protocol 13 has support for authentication plugins (op_cont_auth).
|
||||
|
||||
const USHORT PROTOCOL_VERSION13 = (FB_PROTOCOL_FLAG | 13);
|
||||
|
||||
// Architecture types
|
||||
|
||||
enum P_ARCH
|
||||
@ -292,6 +296,8 @@ enum P_OP
|
||||
|
||||
op_cancel = 91,
|
||||
|
||||
op_cont_auth = 92,
|
||||
|
||||
op_max
|
||||
};
|
||||
|
||||
@ -614,6 +620,12 @@ typedef struct p_trau
|
||||
CSTRING p_trau_data; // Context
|
||||
} P_TRAU;
|
||||
|
||||
typedef struct p_auth_continue
|
||||
{
|
||||
CSTRING p_data; // Request
|
||||
CSTRING p_name; // Plugin name
|
||||
} P_AUTH_CONT;
|
||||
|
||||
struct p_update_account
|
||||
{
|
||||
OBJCT p_account_database; // Database object id
|
||||
@ -674,7 +686,8 @@ typedef struct packet
|
||||
P_TRAU p_trau; // Trusted authentication
|
||||
p_update_account p_account_update;
|
||||
p_authenticate p_authenticate_user;
|
||||
P_CANCEL_OP p_cancel_op; // cancel operation
|
||||
P_CANCEL_OP p_cancel_op; // Cancel operation
|
||||
P_AUTH_CONT p_auth_cont; // Request more auth data
|
||||
|
||||
public:
|
||||
packet()
|
||||
|
@ -725,27 +725,6 @@ bool_t REMOTE_getbytes (XDR* xdrs, SCHAR* buff, u_int count)
|
||||
}
|
||||
#endif //REM_SERVER
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
ServerAuth::ServerAuth(const char* fName, int fLen, const Firebird::ClumpletWriter& pb,
|
||||
ServerAuth::Part2* p2, P_OP op)
|
||||
: fileName(*getDefaultMemoryPool()), clumplet(*getDefaultMemoryPool()),
|
||||
part2(p2), operation(op)
|
||||
{
|
||||
fileName.assign(fName, fLen);
|
||||
size_t pbLen = pb.getBufferLength();
|
||||
if (pbLen)
|
||||
{
|
||||
memcpy(clumplet.getBuffer(pbLen), pb.getBuffer(), pbLen);
|
||||
}
|
||||
authSspi = FB_NEW(*getDefaultMemoryPool()) AuthSspi;
|
||||
}
|
||||
|
||||
ServerAuth::~ServerAuth()
|
||||
{
|
||||
delete authSspi;
|
||||
}
|
||||
#endif // TRUSTED_AUTH
|
||||
|
||||
void PortsCleanup::registerPort(rem_port* port)
|
||||
{
|
||||
Firebird::MutexLockGuard guard(m_mutex);
|
||||
@ -789,6 +768,10 @@ void PortsCleanup::closePorts()
|
||||
}
|
||||
}
|
||||
|
||||
ServerAuthBase::~ServerAuthBase()
|
||||
{
|
||||
}
|
||||
|
||||
rem_port::~rem_port()
|
||||
{
|
||||
if (port_events_shutdown)
|
||||
@ -807,9 +790,7 @@ rem_port::~rem_port()
|
||||
delete port_packet_vector;
|
||||
#endif
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
delete port_trusted_auth;
|
||||
#endif
|
||||
delete port_auth;
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
--portCounter;
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "../jrd/ThreadStart.h"
|
||||
#include "../common/thd.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include "../auth/trusted/AuthSspi.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../common/classes/RefMutex.h"
|
||||
@ -508,23 +507,12 @@ struct rem_que_packet
|
||||
|
||||
typedef Firebird::Array<rem_que_packet> PacketQueue;
|
||||
|
||||
#ifdef TRUSTED_AUTH
|
||||
// delayed authentication block for trusted auth callback
|
||||
class ServerAuth : public Firebird::GlobalStorage
|
||||
class ServerAuthBase
|
||||
{
|
||||
public:
|
||||
typedef void Part2(rem_port*, P_OP, const char* fName, int fLen, const UCHAR* pb, int pbLen, PACKET*);
|
||||
Firebird::PathName fileName;
|
||||
Firebird::HalfStaticArray<UCHAR, 128> clumplet;
|
||||
AuthSspi* authSspi;
|
||||
Part2* part2;
|
||||
P_OP operation;
|
||||
|
||||
ServerAuth(const char* fName, int fLen, const Firebird::ClumpletWriter& pb, Part2* p2, P_OP op);
|
||||
~ServerAuth();
|
||||
virtual ~ServerAuthBase();
|
||||
virtual bool authenticate(rem_port* port, PACKET* send, const cstring* data) = 0;
|
||||
};
|
||||
#endif // TRUSTED_AUTH
|
||||
|
||||
|
||||
// port_flags
|
||||
const USHORT PORT_symmetric = 0x0001; // Server/client architectures are symmetic
|
||||
@ -630,9 +618,7 @@ struct rem_port : public Firebird::GlobalStorage, public Firebird::RefCounted
|
||||
Firebird::ObjectsArray< Firebird::Array<char> > port_queue;
|
||||
size_t port_qoffset; // current packet in the queue
|
||||
#endif
|
||||
#ifdef TRUSTED_AUTH
|
||||
ServerAuth* port_trusted_auth;
|
||||
#endif
|
||||
ServerAuthBase* port_auth;
|
||||
UCharArrayAutoPtr port_buffer;
|
||||
|
||||
public:
|
||||
@ -663,10 +649,7 @@ public:
|
||||
#ifdef REM_SERVER
|
||||
port_queue(getPool()), port_qoffset(0),
|
||||
#endif
|
||||
#ifdef TRUSTED_AUTH
|
||||
port_trusted_auth(0),
|
||||
#endif
|
||||
port_buffer(FB_NEW(getPool()) UCHAR[rpt])
|
||||
port_auth(0), port_buffer(FB_NEW(getPool()) UCHAR[rpt])
|
||||
{
|
||||
addRef();
|
||||
memset (&port_linger, 0, sizeof port_linger);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -248,10 +248,6 @@ rem_port* XNET_analyze(const Firebird::PathName& file_name,
|
||||
cnct->p_cnct_file.cstr_length = (USHORT) file_name.length();
|
||||
cnct->p_cnct_file.cstr_address = reinterpret_cast<const UCHAR*>(file_name.c_str());
|
||||
|
||||
// Note: prior to V3.1E a recievers could not in truth handle more
|
||||
// then 5 protocol descriptions; however, the interprocess server
|
||||
// was created in 4.0 so this does not apply.
|
||||
|
||||
cnct->p_cnct_user_id.cstr_length = (USHORT) user_id.getBufferLength();
|
||||
cnct->p_cnct_user_id.cstr_address = user_id.getBuffer();
|
||||
|
||||
@ -261,7 +257,8 @@ rem_port* XNET_analyze(const Firebird::PathName& file_name,
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION8, ptype_rpc, ptype_batch_send, 2),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION10, ptype_rpc, ptype_batch_send, 3),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION11, ptype_rpc, ptype_batch_send, 4),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION12, ptype_rpc, ptype_batch_send, 5)
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION12, ptype_rpc, ptype_batch_send, 5),
|
||||
REMOTE_PROTOCOL(PROTOCOL_VERSION13, ptype_rpc, ptype_batch_send, 6)
|
||||
};
|
||||
cnct->p_cnct_count = FB_NELEM(protocols_to_try1);
|
||||
|
||||
|
@ -161,7 +161,7 @@ int gsec(Firebird::UtilSvc* uSvc)
|
||||
else
|
||||
{
|
||||
TEXT database_name[MAXPATHLEN];
|
||||
Jrd::SecurityDatabase::getPath(database_name);
|
||||
Auth::SecurityDatabase::getPath(database_name);
|
||||
databaseName = database_name;
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status,
|
||||
**************************************/
|
||||
Firebird::MutexLockGuard guard(execLineMutex);
|
||||
|
||||
SCHAR encrypted1[MAX_PASSWORD_LENGTH + 2];
|
||||
SCHAR encrypted1[Auth::MAX_PASSWORD_LENGTH + 2];
|
||||
Firebird::string encrypted2;
|
||||
bool found;
|
||||
SSHORT ret = 0;
|
||||
@ -213,8 +213,8 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status,
|
||||
U.GROUP_NAME.NULL = ISC_TRUE;
|
||||
if (io_user_data->password_entered)
|
||||
{
|
||||
ENC_crypt(encrypted1, sizeof encrypted1, io_user_data->password, PASSWORD_SALT);
|
||||
Jrd::SecurityDatabase::hash(encrypted2, io_user_data->user_name, &encrypted1[2]);
|
||||
ENC_crypt(encrypted1, sizeof encrypted1, io_user_data->password, Auth::PASSWORD_SALT);
|
||||
Auth::SecurityDatabase::hash(encrypted2, io_user_data->user_name, &encrypted1[2]);
|
||||
strcpy(U.PASSWD, encrypted2.c_str());
|
||||
U.PASSWD.NULL = ISC_FALSE;
|
||||
}
|
||||
@ -284,8 +284,8 @@ SSHORT SECURITY_exec_line(ISC_STATUS* isc_status,
|
||||
U.GROUP_NAME.NULL = ISC_TRUE;
|
||||
if (io_user_data->password_entered)
|
||||
{
|
||||
ENC_crypt(encrypted1, sizeof encrypted1, io_user_data->password, PASSWORD_SALT);
|
||||
Jrd::SecurityDatabase::hash(encrypted2, io_user_data->user_name, &encrypted1[2]);
|
||||
ENC_crypt(encrypted1, sizeof encrypted1, io_user_data->password, Auth::PASSWORD_SALT);
|
||||
Auth::SecurityDatabase::hash(encrypted2, io_user_data->user_name, &encrypted1[2]);
|
||||
strcpy(U.PASSWD, encrypted2.c_str());
|
||||
U.PASSWD.NULL = ISC_FALSE;
|
||||
}
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include "../../jrd/req.h"
|
||||
#include "../../jrd/svc.h"
|
||||
#include "../../jrd/os/path_utils.h"
|
||||
#include "../../jrd/inf_pub.h"
|
||||
#include "../../dsql/sqlda_pub.h"
|
||||
|
||||
|
||||
using namespace Firebird;
|
||||
|
Loading…
Reference in New Issue
Block a user