From 7bab83873b519ec8be7d4ce67a2aea74889c6081 Mon Sep 17 00:00:00 2001 From: Roberta Marton Date: Wed, 14 Sep 2016 17:24:55 +0000 Subject: [PATCH 1/2] [TRAFODION-1794]: Log authentication Information Added code to log LDAP connection errors into the associated log4cxx file. For authentications that occur in mxosrvr, events are logged into the master executor log. For standalone utilities such as ldapcheck, events are logged into a separate file with names: dbsecurity__.log. This code was donated to the Trafodion team and it originally logged events into a repository table and/or a stdout log. This change will log authentication details into the standard log4cxx logs. Session information is being logged into repository tables which describe connection attributes but detailed LDAP errors will be only put in the logs. The ldapcheck utility has been instrumented to log errors in the logs directory previously, errors were not logged. This will be needed when TRAFODION-1787 is implemented. The files authEvent.h and authEvents.cpp replace existing files called ld_globals.h and ld_port.cpp. --- core/dbsecurity/auth/Makefile | 22 +- core/dbsecurity/auth/depend.mk | 8 +- core/dbsecurity/auth/inc/auth.h | 11 + core/dbsecurity/auth/inc/authEvents.h | 89 +++++ core/dbsecurity/auth/inc/ld_globals.h | 48 --- core/dbsecurity/auth/src/authEvents.cpp | 134 +++++++ core/dbsecurity/auth/src/dbUserAuth.cpp | 333 +++++++++++------- core/dbsecurity/auth/src/ld_port.cpp | 201 ----------- core/dbsecurity/auth/src/ldapcheck.cpp | 228 ++++-------- core/dbsecurity/auth/src/ldapconfignode.cpp | 195 +++++----- core/dbsecurity/macros.gmk | 8 +- core/sqf/conf/log4cxx.trafodion.auth.config | 49 +++ .../include/common/evl_sqlog_eventnum.h | 3 +- 13 files changed, 678 insertions(+), 651 deletions(-) create mode 100644 core/dbsecurity/auth/inc/authEvents.h delete mode 100644 core/dbsecurity/auth/inc/ld_globals.h create mode 100644 core/dbsecurity/auth/src/authEvents.cpp delete mode 100644 core/dbsecurity/auth/src/ld_port.cpp create mode 100644 core/sqf/conf/log4cxx.trafodion.auth.config diff --git a/core/dbsecurity/auth/Makefile b/core/dbsecurity/auth/Makefile index f916a94a17..acb26f6f59 100644 --- a/core/dbsecurity/auth/Makefile +++ b/core/dbsecurity/auth/Makefile @@ -27,6 +27,7 @@ include $(MY_SQROOT)/macros.gmk #top level include ../macros.gmk #OUTDIR = . + RM = /bin/rm CP = /bin/cp DBG_FLAGS = $(DBG_FLGS) @@ -37,8 +38,10 @@ all: $(LIBEXPDIR)/libsqauth.so $(BINEXPDIR)/ldapconfigcheck $(BINEXPDIR)/ldapche #Source files required to build the library OBJS = $(OUTDIR)/dbUserAuth.o \ - $(OUTDIR)/ldapconfignode.o $(OUTDIR)/ld_port.o \ + $(OUTDIR)/ldapconfignode.o \ + $(OUTDIR)/authEvents.o \ $(OUTDIR)/ldapconfigfile.o \ + $(OUTDIR)/CommonLogger.o \ $(OUTDIR)/token.o \ $(OUTDIR)/tokenkey.o \ $(OUTDIR)/verssqauth.o @@ -50,16 +53,10 @@ OBJS2 = \ OBJS3 = \ $(OUTDIR)/ldapconfignode.o \ + $(OUTDIR)/authEvents.o \ $(OUTDIR)/versldapcheck.o \ $(OUTDIR)/ldapcheck.o \ - $(OUTDIR)/ldapconfigfile.o - -OBJS4 = \ - $(OUTDIR)/ldapconfignode.o \ - $(OUTDIR)/dbUserAuth.o \ - $(OUTDIR)/dbuserauthcheck.o \ - $(OUTDIR)/token.o \ - $(OUTDIR)/tokenkey.o \ + $(OUTDIR)/CommonLogger.o \ $(OUTDIR)/ldapconfigfile.o @@ -70,10 +67,11 @@ INCLUDES = -I. -I./inc -I ../shared/inc \ -I $(MY_SQROOT)/../sql/export \ -I $(MY_SQROOT)/../sql/porting_layer \ -I $(MY_SQROOT)/export/include \ + -I $(MY_SQROOT)/commonLogger \ -I ../../sql/common -LINK_OPTIONS = -L$(LIBEXPDIR) -lldap -lssl -llber +LINK_OPTIONS = -L$(LIBEXPDIR) -lldap -lssl -llber -llog4cxx LINK_OPTIONS += $(LNK_FLGS) COMMON_LIBS = -ltdm_sqlcli -larkcmp_dll @@ -93,9 +91,6 @@ $(BINEXPDIR)/ldapconfigcheck: $(OBJS2) $(BINEXPDIR)/ldapcheck: $(OBJS3) $(CXX) -fPIC $(DBG_FLAGS) $(GCCMODEXX) -o $@ $(INCLUDES) $(LINK_OPTIONS) $(OBJS3) -$(BINEXPDIR)/dbuserauthcheck: $(OBJS4) - $(CXX) -fPIC $(DBG_FLAGS) $(GCCMODEXX) -o $@ $(INCLUDES) $(LINK_OPTIONS) $(COMMON_LIBS) $(OBJS4) - clean: @@ -105,7 +100,6 @@ clean: $(RM) -f $(LIBEXPDIR)/libsqauth.so $(RM) -f $(INCEXPDIR)/dbUserAuth.h $(RM) -f $(INCEXPDIR)/auth.h - $(RM) -f $(BINEXPDIR)/dbuserauthcheck $(RM) -f $(BINEXPDIR)/ldapcheck $(RM) -f $(BINEXPDIR)/ldapconfigcheck diff --git a/core/dbsecurity/auth/depend.mk b/core/dbsecurity/auth/depend.mk index cc9d766f85..8657c33c10 100644 --- a/core/dbsecurity/auth/depend.mk +++ b/core/dbsecurity/auth/depend.mk @@ -38,12 +38,14 @@ $(OUTDIR)/dbUserAuth.o: inc/auth.h $(OUTDIR)/dbUserAuth.o: inc/token.h $(OUTDIR)/dbUserAuth.o: inc/tokenkey.h $(OUTDIR)/dbUserAuth.o: inc/ldapconfignode.h -$(OUTDIR)/dbUserAuth.o: inc/ld_globals.h +$(OUTDIR)/dbUserAuth.o: inc/authEvents.h $(OUTDIR)/ldapconfignode.o: inc/ldapconfignode.h -$(OUTDIR)/ldapconfignode.o: inc/ld_globals.h +$(OUTDIR)/ldapconfignode.o: inc/authEvents.h -$(OUTDIR)/ld_port.o: inc/ld_globals.h +$(OUTDIR)/authEvents.o: inc/authEvents.h + +$(OUTDIR)/ldapcheck.o: inc/authEvents.h $(OUTDIR)/token.o: inc/token.h $(OUTDIR)/token.o: inc/tokenkey.h diff --git a/core/dbsecurity/auth/inc/auth.h b/core/dbsecurity/auth/inc/auth.h index 2b51371031..68d9b42300 100644 --- a/core/dbsecurity/auth/inc/auth.h +++ b/core/dbsecurity/auth/inc/auth.h @@ -49,6 +49,17 @@ enum UA_Status{ UA_STATUS_PARAM5 = 5 }; +enum AUTH_OUTCOME{ + AUTH_OK = 0, + AUTH_NOT_REGISTERED = 1, + AUTH_MD_NOT_AVAILABLE = 2, + AUTH_USER_INVALID = 3, + AUTH_TYPE_INCORRECT = 4, + AUTH_NO_PASSWORD = 5, + AUTH_REJECTED = 6, + AUTH_FAILED = 7 +}; + // Define a struct to populate the fields needed by authentication audit typedef struct client_info diff --git a/core/dbsecurity/auth/inc/authEvents.h b/core/dbsecurity/auth/inc/authEvents.h new file mode 100644 index 0000000000..8c4cefaba4 --- /dev/null +++ b/core/dbsecurity/auth/inc/authEvents.h @@ -0,0 +1,89 @@ +//****************************************************************************** +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ +//****************************************************************************** +#ifndef INCLUDE_AUTHEVENT_H +#define INCLUDE_AUTHEVENT_H 1 +#include "common/evl_sqlog_eventnum.h" +#include "CommonLogger.h" +#include +#include + +// From a web search, the log message max length is a bit over 8000 bytes. +// For DBSecurity don't believe any messages will be more than 1M +#define MAX_EVENT_MSG_SIZE 1024 + +// The ported code had the caller sending in the filename and line number +// for certain events. This has not been implemented at this time. +struct AuthEvent +{ + DB_SECURITY_EVENTID eventID_; + std::string eventText_; + logLevel severity_; + std::string filename_; + int32_t lineNumber_; + std::string callerName_; + + AuthEvent () + : eventID_ (DBS_GENERIC_ERROR), + severity_ (LL_INFO), + lineNumber_ (0), + callerName_ ("??") + {} + + AuthEvent ( + DB_SECURITY_EVENTID eventID, + std::string eventText, + logLevel severity) + : eventID_ (eventID), + eventText_ (eventText), + severity_ (severity), + lineNumber_(0), + callerName_ ("??") + {} + + DB_SECURITY_EVENTID getEventID () { return eventID_; } + logLevel getSeverity() { return severity_; } + int32_t getLineNum() { return lineNumber_; } + std::string getEventText() { return eventText_; } + std::string getFilename() { return filename_; } + std::string getCallerName() { return callerName_; } + + void setCallerName (std::string callerName) { callerName_ = callerName; } + void setLineNumber(int32_t lineNumber) { lineNumber_ = lineNumber; } + void setFilename(std::string filename) { filename_ = filename; } + + static std::string formatEventText( const char * eventText ); + + void logAuthEvent (); + +}; + +extern std::vector authEvents; + +void authInitEventLog(); + +void insertAuthEvent( + DB_SECURITY_EVENTID eventID, + const char * eventText, + logLevel severity); + +#endif diff --git a/core/dbsecurity/auth/inc/ld_globals.h b/core/dbsecurity/auth/inc/ld_globals.h deleted file mode 100644 index 4bd5a223b8..0000000000 --- a/core/dbsecurity/auth/inc/ld_globals.h +++ /dev/null @@ -1,48 +0,0 @@ -//****************************************************************************** -// @@@ START COPYRIGHT @@@ -// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -// -// @@@ END COPYRIGHT @@@ -//****************************************************************************** -#ifndef INCLUDE_LD_GLOBALS_H -#define INCLUDE_LD_GLOBALS_H 1 -#include "common/evl_sqlog_eventnum.h" -#include - -struct AuthEvents -{ -DB_SECURITY_EVENTID eventID; -std::string eventText; -std::string filename; -int32_t lineNumber; -}; - -void clearAuthEvents(); - -size_t getAuthEventCount(); - -const AuthEvents & getAuthEvent(size_t index); - -void logAuthEvent( - DB_SECURITY_EVENTID eventID, - const char * msg, - const std::string & file_name, - int32_t line_number); - -#endif diff --git a/core/dbsecurity/auth/src/authEvents.cpp b/core/dbsecurity/auth/src/authEvents.cpp new file mode 100644 index 0000000000..19cd90cd52 --- /dev/null +++ b/core/dbsecurity/auth/src/authEvents.cpp @@ -0,0 +1,134 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +#include "authEvents.h" +#include +#include +#include +#include +#include +#include "seabed/ms.h" +#include "seabed/fserr.h" + +static std::string AUTH_COMPONENT = "DBSECURITY"; +std::vector authEvents; + +// **************************************************************************** +// function: insertAuthEvent +// +// This function inserts an AuthEvent into the current list of authEvents +// +// DB_SECUITY_EVENTID - is the event ID to insert +// see: $MY_SQROOT/log4cxx.trafodion.auth.config/evl_sqlog_eventnum.h +// eventText - text to insert +// severity - severity of the event +// **************************************************************************** +void insertAuthEvent( + DB_SECURITY_EVENTID eventID, + const char * eventText, + logLevel severity) +{ + AuthEvent authEvent(eventID, + AuthEvent::formatEventText(eventText), + severity); + authEvents.push_back(authEvent); +} + +// **************************************************************************** +// function authInitEventLog() +// +// This function create a new log in $MY_SQROOT/logs directory with the +// following name dbsecurity__.log +// +// It is called for standalone executables (e.g. ldapcheck) to log issues +// When users are authenticated during client authentication (mxosrvr), it +// is assumed that the event log has already been initialized. +// +// **************************************************************************** +void authInitEventLog() +{ + // Log4cxx logging + int my_nid = 1; + + // get my pid + my_nid = getpid(); + char my_hostname[HOST_NAME_MAX+1]; + Int32 result; + + // who am I? + if (gethostname(my_hostname,HOST_NAME_MAX) != 0) + strcpy(my_hostname, "unknown"); + + int log_name_suffix_len = strlen(my_hostname) + 32; + char log_name_suffix[log_name_suffix_len]; + snprintf( log_name_suffix, log_name_suffix_len, "_%s_%d.log", my_hostname, my_nid ); + CommonLogger::instance().initLog4cxx("log4cxx.trafodion.auth.config",log_name_suffix); +} + +// **************************************************************************** +// method: AuthEvent::formatEventText +// +// This method formats event text into a message that can be added to the +// cxx log. +// +// eventText - the text to be logged +// **************************************************************************** +std::string AuthEvent::formatEventText( const char * eventText ) +{ + // Format the timestamp + char tbuff[24] = {0}; + struct tm *stm; + + time_t now = time(0); + stm = gmtime(&now); + strftime(tbuff, sizeof(tbuff), "%Y-%m-%d %H:%M:%S %Z", stm); + + // Format the event message, with the timestamp at the beginning. + char eventMessage[MAX_EVENT_MSG_SIZE]; + snprintf(eventMessage, MAX_EVENT_MSG_SIZE, "%s (pid=%d) %s", tbuff, getpid(), eventText); + + std::string newMessage(eventMessage); + return newMessage; +} + +// **************************************************************************** +// method: AuthEvent::logAuthEvent +// +// This method writes the AuthEvent to the cxx log +// +// **************************************************************************** +void AuthEvent::logAuthEvent() +{ + int my_nid = 0; //gethostid()? + int my_pid = getpid(); + int my_cpu = 0; + + // Log4cxx logging + char buf[MAX_EVENT_MSG_SIZE]; + snprintf(buf, MAX_EVENT_MSG_SIZE, "Node Number: %u, CPU: %u, PIN: %u ,,,, Message: %s", + my_nid, my_cpu, my_pid, eventText_.c_str()); + + // strip off final new line before logging + int32_t lastPos = strlen(buf) -1; + if (buf [lastPos] == '\n') + buf[lastPos] = '.'; + CommonLogger::log(AUTH_COMPONENT, severity_, buf); +} diff --git a/core/dbsecurity/auth/src/dbUserAuth.cpp b/core/dbsecurity/auth/src/dbUserAuth.cpp index cf021f5319..3ab2dbedd7 100644 --- a/core/dbsecurity/auth/src/dbUserAuth.cpp +++ b/core/dbsecurity/auth/src/dbUserAuth.cpp @@ -48,7 +48,7 @@ #include #endif -#include "ld_globals.h" +#include "authEvents.h" #include "ldapconfignode.h" #include "common/evl_sqlog_eventnum.h" @@ -102,7 +102,6 @@ static LDAuthStatus executeLDAPAuthentication( const char * username, const char * password, LDAPConfigNode::LDAPConfigType configType, - bool & errorsLogged, PERFORMANCE_INFO & performanceInfo); inline static const UserCacheContents * fetchFromCacheByUsername(const char * username); @@ -124,14 +123,14 @@ static int32_t fetchFromAUTHSTable( int64_t & redefTime); -static void logAuthenticationErrors(int nodeID); +static void logAuthenticationErrors(); static void logAuthenticationOutcome( const string & external_user_name, const string & internal_user_name, const int32_t user_id, ClientContents & clientInfo, - const string & outcome); + const AUTH_OUTCOME outcome); static void logAuthenticationRetries( int nodeID, @@ -1072,19 +1071,21 @@ static void authenticateUser( self.bb.isAuthenticated = false; -long retCode; -bool isValid; -AuthConfigType authType; -USERS_INFO usersInfo; + long retCode; + bool isValid; + AuthConfigType authType; + USERS_INFO usersInfo; -// -// First step; is the user registered. If not, no sense bothering the -// LDAP server. -// + char eventMsg[MAX_EVENT_MSG_SIZE]; + + // + // First step; is the user registered. If not, no sense bothering the + // LDAP server. + // memset(usersInfo.databaseUsername,' ',sizeof(usersInfo.databaseUsername)); strcpy(usersInfo.externalUsername,externalUsername); -int64_t startTime = JULIANTIMESTAMP(); + int64_t startTime = JULIANTIMESTAMP(); retCode = fetchFromAUTHSTable(externalUsername,usersInfo.databaseUsername, usersInfo.sessionUserID,isValid, @@ -1093,13 +1094,13 @@ int64_t startTime = JULIANTIMESTAMP(); performanceInfo.sqlUserTime = JULIANTIMESTAMP() - startTime; if (retCode != 0) { -// LCOV_EXCL_START authenticationInfo.error = self.bb.error = ZFIL_ERR_SECVIOL; // Error 100 (NOT FOUND) means user isn't a registered SQ user. // For now this is an error, in the future there could be an // option to auto-register users. if (retCode == 100) self.bb.errorDetail = UA_STATUS_ERR_INVALID; + else//ACH Should we log other SQL errors here? self.bb.errorDetail = UA_STATUS_ERR_SYSTEM; @@ -1107,17 +1108,16 @@ int64_t startTime = JULIANTIMESTAMP(); logAuthenticationOutcome(usersInfo.externalUsername, usersInfo.databaseUsername, - usersInfo.sessionUserID,clientInfo,"F "); + usersInfo.sessionUserID,clientInfo, + (retCode = 100) ? AUTH_NOT_REGISTERED : AUTH_MD_NOT_AVAILABLE); return; -// LCOV_EXCL_STOP } -// -// User is registered, but is the account still valid? Users can be -// marked offline by ALTER USER command or possibly in the future when -// we detect a registered user is no longer defined on the directory server. -// - + // + // User is registered, but is the account still valid? Users can be + // marked offline by ALTER USER command or possibly in the future when + // we detect a registered user is no longer defined on the directory server. + // if (!isValid) { authenticationInfo.error = self.bb.error = ZFIL_ERR_SECVIOL; @@ -1125,15 +1125,15 @@ int64_t startTime = JULIANTIMESTAMP(); logAuthenticationOutcome(usersInfo.externalUsername, usersInfo.databaseUsername, - usersInfo.sessionUserID,clientInfo,"F "); + usersInfo.sessionUserID,clientInfo,AUTH_USER_INVALID); return; } -// -// User is registered and valid, but is the authentication type recognized? -// If not, reject the authentication. -// -//ACH not in metadata currently. + // + // User is registered and valid, but is the authentication type recognized? + // If not, reject the authentication. + // + //ACH not in metadata currently. /* if (authType == AuthUnknownConfiguration) { @@ -1142,13 +1142,13 @@ int64_t startTime = JULIANTIMESTAMP(); logAuthenticationOutcome(usersInfo.externalUsername, usersInfo.databaseUsername, - usersInfo.sessionUserID,clientInfo,"F "); + usersInfo.sessionUserID,clientInfo,AUTH_USER_INVALID); return; } */ -// -// Let's check on the credentials first. -// + // + // Let's check on the credentials first. + // if (strlen(password) == 0) { // zero len password is a non-auth bind in LDAP, so we treat it @@ -1157,46 +1157,33 @@ int64_t startTime = JULIANTIMESTAMP(); authenticationInfo.errorDetail = self.bb.errorDetail = UA_STATUS_ERR_INVALID; logAuthenticationOutcome(usersInfo.externalUsername, usersInfo.databaseUsername, - usersInfo.sessionUserID,clientInfo,"F "); + usersInfo.sessionUserID,clientInfo,AUTH_NO_PASSWORD); return; } -LDAuthStatus authStatus = LDAuthSuccessful; -bool errorsLogged = false; + LDAuthStatus authStatus = LDAuthSuccessful; -// -// Next step, see if the user is defined on the LDAP server. -// + // + // Next step, see if the user is defined on the LDAP server. + // -//ACH For now, only support primary configuration + //ACH For now, only support primary configuration authStatus = executeLDAPAuthentication(self,usersInfo.externalUsername, password, LDAPConfigNode::PrimaryConfiguration, - errorsLogged, performanceInfo); -// We log errors encountered in LDAP authentication to the repository. -// We can't log within the LDAP authentication module since other clients -// don't include the necessary libraries. executeLDAPAuthentication() may -// have already logged the internal error(s); if not, log them now. - if (!errorsLogged) - { - logAuthenticationErrors(self.nodeID); - errorsLogged = true; - } -// We log retries regardless of whether the authentication succeeded -// or failed. Logging the retries for failed authentications shows -// problem was not transient. Logging retries when the -// authentication was successful allows operations to be aware of -// potential problems. - logAuthenticationRetries(self.nodeID,externalUsername); - -// -// If all is well, save all the relevant user data in our container. -// + // + // If all is well, save all the relevant user data in our container. + // if (authStatus == LDAuthSuccessful) { + // Logging retries when the authentication was successful allows + // operations to be aware of potential problems. + // Retries are logged later for unsuccessful authentications. + logAuthenticationRetries(self.nodeID,externalUsername); + // Strings returned from SQL could have trailing blanks and nulls // Remove all trailing blanks so callers have an accurate length // for comparison. @@ -1205,7 +1192,8 @@ bool errorsLogged = false; strcpy(authenticationInfo.usersInfo.databaseUsername,usersInfo.databaseUsername); strcpy(authenticationInfo.usersInfo.externalUsername,externalUsername); usersInfo.effectiveUserID = usersInfo.sessionUserID; - // Copy USERS_INFO fields. Class, = operator, byte copy + + // Copy USERS_INFO fields. Class, = operator, byte copy authenticationInfo.usersInfo.effectiveUserID = usersInfo.effectiveUserID; authenticationInfo.usersInfo.sessionUserID = usersInfo.sessionUserID; authenticationInfo.usersInfo.redefTime = usersInfo.redefTime; @@ -1222,21 +1210,22 @@ bool errorsLogged = false; strcpy(self.bb.usersInfo.databaseUsername,usersInfo.databaseUsername); strcpy(self.bb.usersInfo.externalUsername,externalUsername); self.bb.isAuthenticated = true; - // Log the successful authentication to the audit log repository. + + // Log the successful authentication to the log repository. logAuthenticationOutcome(externalUsername,usersInfo.databaseUsername, - usersInfo.sessionUserID,clientInfo,"S "); + usersInfo.sessionUserID,clientInfo,AUTH_OK); return; } -// -// Rejected! -// -// Either the provided password does not match the one stored on the LDAP -// server or we had internal problems with the server. -// -// No soup for you. -// + // + // Rejected! + // + // Either the provided password does not match the one stored on the LDAP + // server or we had internal problems with the server. + // + // No soup for you. + // authenticationInfo.error = ZFIL_ERR_SECVIOL; self.bb.error = ZFIL_ERR_SECVIOL; @@ -1248,9 +1237,12 @@ bool errorsLogged = false; } authenticationInfo.errorDetail = self.bb.errorDetail; -// Log the failed authentication to the audit log repository. + // Log the failed authentication to the log repository. logAuthenticationOutcome(externalUsername,usersInfo.databaseUsername, - usersInfo.sessionUserID,clientInfo,"F "); + usersInfo.sessionUserID,clientInfo, + (authStatus = LDAuthRejected) ? AUTH_REJECTED : AUTH_FAILED); + // Log any events generated + logAuthenticationErrors(); } //************************** End of authenticateUser *************************** @@ -1321,7 +1313,7 @@ UserCacheContents userInfo; // * * // * DBUserAuthContents & In/Out * // * is a reference to a DBUserAuthContents object. Results of the * -// * authentication are stored here. * +// * authentication are stored here. * // * * // * const char * In * // * is the username. Username must be defined on LDAP server. * @@ -1332,10 +1324,6 @@ UserCacheContents userInfo; // * LDAPConfigNode::LDAPConfigType In * // * is the LDAP configuration to use, either primary or secondary. * // * * -// * bool & In * -// * passes back true if an internal error was logged to the repository, * -// * otherwise false. * -// * * // ***************************************************************************** static LDAuthStatus executeLDAPAuthentication( @@ -1343,41 +1331,43 @@ static LDAuthStatus executeLDAPAuthentication( const char * username, const char * password, LDAPConfigNode::LDAPConfigType configType, - bool & errorsLogged, PERFORMANCE_INFO & performanceInfo) { LDAPConfigNode::ClearRetryCounts(); - clearAuthEvents(); - errorsLogged = false; + authEvents.clear(); -// -// First get a search connection for the specified configuration. -// If we can't get a search connection, could be network problem or a -// bad configuration. Either way, tough luck for the user. -// - -int64_t startTime = JULIANTIMESTAMP(); -LDAPConfigNode *searchNode = LDAPConfigNode::GetLDAPConnection(configType, + // + // First get a search connection for the specified configuration. + // If we can't get a search connection, could be network problem or a + // bad configuration. Either way, tough luck for the user. + // + + int64_t startTime = JULIANTIMESTAMP(); + LDAPConfigNode *searchNode = LDAPConfigNode::GetLDAPConnection(configType, SearchConnection); performanceInfo.searchConnectionTime = JULIANTIMESTAMP() - startTime; + char eventMsg[MAX_EVENT_MSG_SIZE]; + if (searchNode == NULL) { -// LCOV_EXCL_START self.bb.error = ZFIL_ERR_SECVIOL; self.bb.errorDetail = UA_STATUS_ERR_SYSTEM; + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, + "Failed to get LDAP connection for user %s",username); + insertAuthEvent(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); + return LDAuthResourceFailure; -// LCOV_EXCL_STOP } -string userDN = ""; // User DN, used to bind to LDAP serer + string userDN = ""; // User DN, used to bind to LDAP serer startTime = JULIANTIMESTAMP(); -LDSearchStatus searchStatus = searchNode->lookupUser(username,userDN); + LDSearchStatus searchStatus = searchNode->lookupUser(username,userDN); performanceInfo.searchTime = JULIANTIMESTAMP() - startTime; @@ -1385,30 +1375,34 @@ LDSearchStatus searchStatus = searchNode->lookupUser(username,userDN); { self.bb.error = ZFIL_ERR_SECVIOL; self.bb.errorDetail = UA_STATUS_ERR_INVALID; + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, + "Failed LDAP search for user %s",username); + insertAuthEvent(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); return LDAuthRejected; } if (searchStatus != LDSearchFound) { -// LCOV_EXCL_START self.bb.error = ZFIL_ERR_SECVIOL; self.bb.errorDetail = UA_STATUS_ERR_SYSTEM; + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, + "Failed LDAP search for user %s",username); + insertAuthEvent(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); return LDAuthResourceFailure; -// LCOV_EXCL_STOP } -// (searchStatus == LDSearchFound) -// ACH: Should we compare UUIDOnLDAP and dsUUID and give "not registered" -// (or some other) error if they don't match? + // (searchStatus == LDSearchFound) + // ACH: Should we compare UUIDOnLDAP and dsUUID and give "not registered" + // (or some other) error if they don't match? -// -// User is defined here and there. But is their password correct? -// Let's get an authentication connection to check on the password -// + // + // User is defined here and there. But is their password correct? + // Let's get an authentication connection to check on the password + // startTime = JULIANTIMESTAMP(); -LDAPConfigNode *authNode = LDAPConfigNode::GetLDAPConnection(configType, + LDAPConfigNode *authNode = LDAPConfigNode::GetLDAPConnection(configType, AuthenticationConnection); performanceInfo.authenticationConnectionTime = JULIANTIMESTAMP() - startTime; @@ -1417,15 +1411,18 @@ LDAPConfigNode *authNode = LDAPConfigNode::GetLDAPConnection(configType, { self.bb.error = ZFIL_ERR_SECVIOL; self.bb.errorDetail = UA_STATUS_ERR_SYSTEM; + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, + "Failed LDAP search on password for user %s",username); + insertAuthEvent(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); return LDAuthResourceFailure; } -// -// Non-blank password, a user we know about, let's validate that password! -// + // + // Non-blank password, a user we know about, let's validate that password! + // startTime = JULIANTIMESTAMP(); -LDAuthStatus authStatus = authNode->authenticateUser(userDN.c_str(),password); + LDAuthStatus authStatus = authNode->authenticateUser(userDN.c_str(),password); performanceInfo.authenticationTime = JULIANTIMESTAMP() - startTime; @@ -1792,22 +1789,25 @@ size_t cacheCount = userCache.size(); // * * // * Function: logAuthenticationErrors * // * * -// * Logs resource failure errors encountered during authentication. * +// * Logs resource failure errors encountered during authentication. * // * Resource failure errors include problems with the * // * configuration in .traf_authrntication_config, network issues, * // * LDAP server issues, or coding blunders. * // * * -// ***************************************************************************** -// * * -// * Parameters: * -// * * -// * int In * -// * is the ID of the node we are running on. * +// * Resource failures have already been inserted into authEvents structure * // * * // ***************************************************************************** -static void logAuthenticationErrors(int nodeID) +static void logAuthenticationErrors() { + size_t errorCount = authEvents.size(); + + for (size_t i = 0; i < errorCount; i++) + { + AuthEvent authEvent = authEvents[i]; + authEvent.setCallerName("mxosrvr"); + authEvent.logAuthEvent(); + } } //************************ End of logAuthenticationErrors ********************** @@ -1837,13 +1837,74 @@ static void logAuthenticationErrors(int nodeID) // * * // ***************************************************************************** static void logAuthenticationOutcome( - const string & external_user_name, - const string & internal_user_name, - const int32_t user_id, - ClientContents & clientInfo, - const string & outcome) + const string & external_user_name, + const string & internal_user_name, + const int32_t user_id, + ClientContents & clientInfo, + const AUTH_OUTCOME outcome) { + string internalUser("??"); + if (user_id > 0) + internalUser = internal_user_name; + logLevel severity = LL_INFO; + + // Currently this code has hard coded error messages in many places, this + // need to be fixed in order to allow errors to be reported in different + // languages. + string outcomeDesc; + switch (outcome) + { + case AUTH_OK: + outcomeDesc = "Authentication successful"; + severity = LL_INFO; + break; + case AUTH_NOT_REGISTERED: + outcomeDesc = "User not registered"; + break; + case AUTH_MD_NOT_AVAILABLE: + outcomeDesc = "Unexpected error occurred looking up user in database"; + severity = LL_INFO; + break; + case AUTH_USER_INVALID: + outcomeDesc = "User is not valid"; + severity = LL_INFO; + break; + case AUTH_TYPE_INCORRECT: + outcomeDesc = "Unexpected authorization type detected"; + severity = LL_INFO; + break; + case AUTH_NO_PASSWORD: + outcomeDesc = "Invalid password"; + severity = LL_INFO; + break; + case AUTH_REJECTED: + outcomeDesc = "Invalid username or password"; + severity = LL_INFO; + break; + case AUTH_FAILED: + outcomeDesc = "Unexpected error returned from LDAP"; + severity = LL_ERROR; + break; + default: + severity = LL_ERROR; + outcomeDesc = "Unexpected error occurred"; + } + + char buf[MAX_EVENT_MSG_SIZE]; + snprintf(buf, MAX_EVENT_MSG_SIZE, + "Outcome -> externalUser: %s, " + "databaseUser: %s, userID: %u, " + "clientName: %s, clientUserName: %s, " + "result: %d (%s)", + external_user_name.c_str(), + internalUser.c_str(), user_id, + clientInfo.clientName, clientInfo.clientUserName, + outcome, outcomeDesc.c_str()); + std::string msg(buf); + AuthEvent authEvent (DBS_AUTHENTICATION_ATTEMPT,msg, severity); + authEvent.setCallerName("mxosrvr"); + authEvent.logAuthEvent(); } //*********************** End of logAuthenticationOutcome ********************** @@ -1873,6 +1934,40 @@ static void logAuthenticationRetries( const char * username) { + size_t bindRetryCount = LDAPConfigNode::GetBindRetryCount(); + size_t searchRetryCount = LDAPConfigNode::GetSearchRetryCount(); + + // If there were no retries, there is nothing to log. + if (bindRetryCount == 0 && searchRetryCount == 0) + return; + + char buf[MAX_EVENT_MSG_SIZE]; + + // Log if the search (name lookup) operation had to be retried. + if (searchRetryCount > 0) + { + snprintf(buf,MAX_EVENT_MSG_SIZE, + "Authentication for user %s required %d search retries. ", + username,searchRetryCount); + + std::string msg(buf); + AuthEvent authEvent (DBS_AUTH_RETRY_SEARCH, msg, LL_INFO); + authEvent.setCallerName("mxosrvr"); + authEvent.logAuthEvent(); + } + + // Log if the bind (password authentication) operation had to be retried. + if (bindRetryCount > 0) + { + snprintf(buf,MAX_EVENT_MSG_SIZE, + "Authentication for user %s required %d bind retries. ", + username,bindRetryCount); + + std::string msg(buf); + AuthEvent authEvent (DBS_AUTH_RETRY_BIND, msg, LL_INFO); + authEvent.setCallerName("mxosrvr"); + authEvent.logAuthEvent(); + } } //*********************** End of logAuthenticationRetries ********************** diff --git a/core/dbsecurity/auth/src/ld_port.cpp b/core/dbsecurity/auth/src/ld_port.cpp deleted file mode 100644 index d8047df3c9..0000000000 --- a/core/dbsecurity/auth/src/ld_port.cpp +++ /dev/null @@ -1,201 +0,0 @@ -//****************************************************************************** -// @@@ START COPYRIGHT @@@ -// -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -// -// @@@ END COPYRIGHT @@@ -//****************************************************************************** -#include -#include -#include -#include -#include -#include -#include -#include "ld_globals.h" - -// LCOV_EXCL_START - - -// ACH: -// This function prints to stdout when there is a problem in -// handling the connection to the LDAP server for user authorization -// or to verify a user exists on the LDAP server. This may be -// due to network problems or a misconfiguration in the .sqldapconfig -// file. When using the internal development tool sqlci, this output -// will go to the user's screen. For customer tools (HPDM or HPDCI) -// stdout gets redirected to a file, so this will be saved in the -// log file on the node. This can be very handy for diagnosing -// connection & configuration problems. -// -// A suggestion has also been made that the CLI code which ends up calling -// the user authentication code as well as DDL code like Register User could -// check first that the LDAP configuration needed is at least present. This -// would allow for better error reporting, for example, in cases where REMOTE -// AUTHENTICATION is specified but the remote connection is not configured in -// the .sqldapconfig file. -// -// - -std::vector authEvents; - -// ***************************************************************************** -// * * -// * Function: clearAuthEvents * -// * * -// * Clears all entries from the authentication events vector. * -// * * -// ***************************************************************************** -void clearAuthEvents() - -{ - - authEvents.clear(); - -} -//************************* End of clearAuthEvents ***************************** - - -// ***************************************************************************** -// * * -// * Function: getAuthEventCount * -// * * -// * Returns the number of entries in the authentication events vector. * -// * * -// ***************************************************************************** -// * * -// * Returns: size_t * -// * * -// ***************************************************************************** -size_t getAuthEventCount() - -{ - - return authEvents.size(); - -} -//************************ End of getAuthEventCount **************************** - - - - - -// ***************************************************************************** -// * * -// * Function: getAuthEvent * -// * * -// * Returns the AuthEvent entry specified by index. * -// * * -// * * -// ***************************************************************************** -// * * -// * Parameter: * -// * * -// * size_t In * -// * is an index into the AuthEvents vector. The index is not validated; * -// * if the index is too large an error will result. * -// * * -// ***************************************************************************** -// * * -// * Returns: const AuthEvents & * -// * * -// ***************************************************************************** -const AuthEvents & getAuthEvent(size_t index) - -{ - - return authEvents[index]; - -} -//*************************** End of getAuthEvent ****************************** - - - - -// ***************************************************************************** -// * * -// * Function: logAuthEvent * -// * * -// * Logs an authentication event (mostly resource errors) to standard out * -// * and stores the event data in a vector for later retrieval. (To be * -// * written to the instance repository in non-Live Feed cases.) * -// * * -// ***************************************************************************** -// * * -// * Parameter: * -// * * -// * DB_SECURITY_EVENTID In * -// * is the event ID associated with the authentication event. * -// * * -// * const char * In * -// * is the text associated with the authentication event. * -// * * -// * const std::string & In * -// * is the filename where the error/event was detected. * -// * * -// * int32_t In * -// * is the line number where the error/event was detected. * -// * * -// * * -// ***************************************************************************** -void logAuthEvent( - DB_SECURITY_EVENTID eventID, - const char * msg, - const std::string & filename, - int32_t lineNumber) - -{ - -// Format the timestamp - -char tbuff[24] = {0}; -struct tm *stm; - - time_t now = time(0); - stm = gmtime(&now); - strftime(tbuff, sizeof(tbuff), "%Y-%m-%d %H:%M:%S %Z", stm); - -// Format the event message, with the timestamp at the beginning. - -char eventMessage[5100]; - - sprintf(eventMessage, - "%s (pid=%d) Error detected while establishing LDAP connection: %s\n", - tbuff, getpid(), msg); - -// Write the event message to the stdout file. - printf(eventMessage); - -// We only store the first 5000 characters of the message. The TEXT column -// is limited to 5000 characters in the EVENT_TEXT_TABLE table. - if (strlen(eventMessage) > 5000) - eventMessage[5000] = 0; - -AuthEvents authEvent; - - authEvent.eventID = eventID; - authEvent.eventText = eventMessage; - authEvent.filename = filename; - authEvent.lineNumber = lineNumber; - authEvents.push_back(authEvent); - -} -//*************************** End of logAuthEvent ****************************** -// LCOV_EXCL_STOP - - diff --git a/core/dbsecurity/auth/src/ldapcheck.cpp b/core/dbsecurity/auth/src/ldapcheck.cpp index 192ba5088c..3b965be69c 100755 --- a/core/dbsecurity/auth/src/ldapcheck.cpp +++ b/core/dbsecurity/auth/src/ldapcheck.cpp @@ -30,6 +30,7 @@ // * //****************************************************************************** #include "ldapconfignode.h" +#include "authEvents.h" #include #include @@ -43,19 +44,9 @@ #include #include #include -#include "common/evl_sqlog_eventnum.h" -using namespace std; -struct AuthEvents -{ -DB_SECURITY_EVENTID eventID; -std::string eventText; -std::string filename; -int32_t lineNumber; -}; - -std::vector authEvents; +using namespace std; enum Operation { Authenticate = 2, @@ -86,12 +77,6 @@ void doCanaryCheck( bool verbose, int & exitCode); -void logAuthEvent( - DB_SECURITY_EVENTID eventID, - const char * msg, - const std::string & filename, - int32_t lineNumber); - LDSearchStatus lookupLDAPUser( const char * username, LDAPConfigNode::LDAPConfigType configType, @@ -99,7 +84,7 @@ LDSearchStatus lookupLDAPUser( void printTime(); -void reportAuthenticationErrors(); +void reportAuthenticationErrors(bool displayErrors); void reportRetries(Operation operation); @@ -261,8 +246,10 @@ LDAPAuthResult rc = authenticateLDAPUser(username,password,configType, if (verbose) { reportRetries(Authenticate); - reportAuthenticationErrors(); + reportAuthenticationErrors(true); } + else + reportAuthenticationErrors(false); } //*************************** End of doAuthenticate **************************** @@ -294,14 +281,13 @@ void doCanaryCheck( int & exitCode) { - exitCode = 0; -char searchHostName[256]; + char searchHostName[256]; searchHostName[0] = 0; -LDSearchStatus searchStatus = lookupLDAPUser(username,configType,searchHostName); + LDSearchStatus searchStatus = lookupLDAPUser(username,configType,searchHostName); if (verbose) cout << "Search host name: " << searchHostName << endl; @@ -330,81 +316,17 @@ LDSearchStatus searchStatus = lookupLDAPUser(username,configType,searchHostName) } if (verbose) - { + { reportRetries(Lookup); - reportAuthenticationErrors(); + reportAuthenticationErrors(true); } + else + reportAuthenticationErrors(false); } //*************************** End of doCanaryCheck ***************************** -// ***************************************************************************** -// * * -// * Function: logAuthEvent * -// * * -// * Stores an authentication event (mostly resource errors) in a vector * -// * for later retrieval. * -// * * -// * The function signature must exactly match the same function in * -// * ld_port.cpp. * -// * * -// ***************************************************************************** -// * * -// * Parameter: * -// * * -// * DB_SECURITY_EVENTID In * -// * is the event ID associated with the authentication event. * -// * * -// * const char * In * -// * is the text associated with the authentication event. * -// * * -// * const std::string & In * -// * is the filename where the error/event was detected. * -// * * -// * int32_t In * -// * is the line number where the error/event was detected. * -// * * -// ***************************************************************************** -void logAuthEvent( - DB_SECURITY_EVENTID eventID, - const char * msg, - const std::string & filename, - int32_t lineNumber) - -{ - -// Format the timestamp - -char tbuff[24] = {0}; -struct tm *stm; - - time_t now = time(0); - stm = gmtime(&now); - strftime(tbuff, sizeof(tbuff), "%Y-%m-%d %H:%M:%S %Z", stm); - -// Format the event message, with the timestamp at the beginning. - -char eventMessage[5100]; - - sprintf(eventMessage, - "%s (pid=%d) Error detected while establishing LDAP connection: %s\n", - tbuff,getpid(),msg); - -AuthEvents authEvent; - - authEvent.eventID = eventID; - authEvent.eventText = eventMessage; - authEvent.filename = filename; - authEvent.lineNumber = lineNumber; - authEvents.push_back(authEvent); - -} -//**************************** End of logAuthEvent ***************************** - - - - // ***************************************************************************** // * * // * Function: lookupLDAPUser * @@ -501,41 +423,30 @@ void printUsage() // ***************************************************************************** -// * * -// * Function: reportAuthenticationErrors * -// * * -// * Displays any resource errors encountered during authentication. * -// * * +// Function: reportAuthenticationErrors +// +// Logs and optionally displays any resource errors encountered during LDAP +// checking. // ***************************************************************************** -void reportAuthenticationErrors() - +void reportAuthenticationErrors(bool displayErrors) { - -size_t errorCount = authEvents.size(); - -// ***************************************************************************** -// * * -// * Walk the list of errors encountered during the attempt to authenticate * -// * the username and password, and for each error, display the event ID and * -// * text along with the file and line number where the error was detected. * -// * * -// * If there is more than one error, number the errors. * -// * * -// ***************************************************************************** - - for (size_t index = 0; index < errorCount; index++) - { - if (errorCount > 1) - cout << "Error #" << index + 1 << endl; - - const AuthEvents &authEvent = authEvents[index]; - - cout << "Filename: " << authEvent.filename << - " Line number: " << authEvent.lineNumber << endl; - cout << "Event ID: " << authEvent.eventID << endl; - cout << authEvent.eventText << endl; - } - + if (authEvents.size() > 0) + authInitEventLog(); + + // Walk the list of errors encountered during the attempt to authenticate + // the username, or username and password, and for each error, log the event + // ID and text. If displayErrors is true and logLevel is above the error + // level, send message to standard out. + std::string callerName ("ldapcheck"); + + for (size_t i = 0; i < authEvents.size(); i++) + { + AuthEvent authEvent = authEvents[i]; + authEvent.setCallerName(callerName); + authEvent.logAuthEvent(); + if (displayErrors) + cout << "ERROR: " << authEvent.getEventText().c_str() << endl; + } } //********************** End of reportAuthenticationErrors ********************* @@ -638,12 +549,8 @@ termios tty; int main(int argc,char *argv[]) { - -// -// ldapcheck needs a username. If not supplied, issue an error -// and print usage information. -// - + // ldapcheck needs a username. If not supplied, issue an error + // and print usage information. if (argc <= 1) { cout << "Username required to check LDAP" << endl; @@ -651,37 +558,31 @@ int main(int argc,char *argv[]) exit(1); } -// -// Help! -// - + // Help! if (strcmp(argv[1],"-h") == 0 || strcmp(argv[1],"--help") == 0) { printUsage(); exit(0); } -enum Options { - Primary = 1, - Secondary = 0, - Platform = 2}; + enum Options { + Primary = 1, + Secondary = 0, + Platform = 2}; -int c; -int optionFlag = Primary; -int verbose = 0; -string password; -char username[129]; -bool usernameSpecified = false; -bool passwordSpecified = false; -int loopCount = 1; -int delayTime = 0; -bool looping = false; - -// -// Walk the list of options. Username and password are required, although -// the password can be left blank and prompted for. -// - + int c; + int optionFlag = Primary; + int verbose = 0; + string password; + char username[129]; + bool usernameSpecified = false; + bool passwordSpecified = false; + int loopCount = 1; + int delayTime = 0; + bool looping = false; + + // Walk the list of options. Username and password are required, although + // the password can be left blank and prompted for. while (true) { static struct option long_options[] = @@ -784,7 +685,7 @@ bool looping = false; } } -// If there are any remaining command line arguments, report an error + // If there are any remaining command line arguments, report an error if (optind < argc) { cout << "Unrecognized text" << endl; @@ -795,7 +696,7 @@ bool looping = false; exit(1); } -// Verify a username was supplied, or we have nothing to do + // Verify a username was supplied, or we have nothing to do if (!usernameSpecified) { cout << "Username required" << endl; @@ -803,7 +704,7 @@ bool looping = false; exit(1); } -LDAPConfigNode::LDAPConfigType configType = LDAPConfigNode::PrimaryConfiguration; + LDAPConfigNode::LDAPConfigType configType = LDAPConfigNode::PrimaryConfiguration; switch (optionFlag) { @@ -820,9 +721,11 @@ LDAPConfigNode::LDAPConfigType configType = LDAPConfigNode::PrimaryConfiguration configType = LDAPConfigNode::PrimaryConfiguration; } -// If no password is supplied, we just perform a name lookup. This was -// added to provide a canary check for the LDAP server without having to -// supply a valid password. + + + // If no password is supplied, we just perform a name lookup. This was + // added to provide a canary check for the LDAP server without having to + // supply a valid password. if (!passwordSpecified) { int exitCode = 0; @@ -834,7 +737,7 @@ LDAPConfigNode::LDAPConfigType configType = LDAPConfigNode::PrimaryConfiguration if (loopCount > 0) sleep(delayTime); } - // + // For the LDAP Canary check mode of ldapcheck, we return one of // three exit codes to be used by a health check: // @@ -842,13 +745,10 @@ LDAPConfigNode::LDAPConfigType configType = LDAPConfigNode::PrimaryConfiguration // 1) LDAP configuration and server(s) good, retries occurred // 2) Could not communicate with LDAP server(s). Check LDAP configuration or server(s). // 3) User was not defined in LDAP - // exit(exitCode); } -// -// We have a username and password. Let's authenticate! -// + // We have a username and password. Let's authenticate! while (loopCount--) { if (verbose && looping) diff --git a/core/dbsecurity/auth/src/ldapconfignode.cpp b/core/dbsecurity/auth/src/ldapconfignode.cpp index eda2cdb0ea..c439ccff6c 100644 --- a/core/dbsecurity/auth/src/ldapconfignode.cpp +++ b/core/dbsecurity/auth/src/ldapconfignode.cpp @@ -1,4 +1,3 @@ -//****************************************************************************** // @@@ START COPYRIGHT @@@ // // Licensed to the Apache Software Foundation (ASF) under one @@ -25,11 +24,12 @@ // from the header files slip into the coverage count - +#include "authEvents.h" #include "ldapconfignode.h" #include "ldapconfigfile.h" #include + // These defines affect openLDAP header files and must appear before s // those includes. @@ -66,7 +66,6 @@ #include #include -#include "ld_globals.h" #include "common/evl_sqlog_eventnum.h" // LCOV_EXCL_STOP @@ -83,11 +82,7 @@ enum NodeState { enum LDAP_VERSIONS { LDAP_VERSION_2 = 2, LDAP_VERSION_3 = 3}; - -// define max size this module uses for an EMS message -#define EMS_MSG_SIZE 500 - -#define LOG_AUTH_EVENT(eventID,eventText) logAuthEvent(eventID,eventText,__FILE__,__LINE__) +#define INSERT_EVENT(eventID,eventText) insertAuthEvent(eventID,eventText,LL_ERROR) static size_t numBindRetries = 0; static size_t numSearchRetries = 0; @@ -783,7 +778,7 @@ LDAuthStatus LDAPConfigNode::authenticateUser( int LDAPError = LDAP_SUCCESS; LD_Status status = LD_STATUS_OK; -char emsMsg[EMS_MSG_SIZE]; +char eventMsg[MAX_EVENT_MSG_SIZE]; LDAuthStatus authStatus = bindUser(self,username,password,true,LDAPError); @@ -834,12 +829,12 @@ int retry_count = self.host_->LDAPConfig_->retryCount; // if (self.host_->LDAPConfig_->retryCount) - sprintf(emsMsg, "Failed to authenticate LDAP user %s after %d retries\n", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to authenticate LDAP user %s after %d retries\n", username,self.host_->LDAPConfig_->retryCount); else - sprintf(emsMsg, "Failed to authenticate LDAP user %s\n",username); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to authenticate LDAP user %s\n",username); - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,emsMsg); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); return LDAuthResourceFailure; } @@ -902,7 +897,7 @@ bool LDAPConfigNode::initialize(char * hostName) // connection and setup the rest of the node. if (!selfCheck(self,false)) { - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in initialize"); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in initialize"); return false; } @@ -956,16 +951,16 @@ int retry_count = self.host_->LDAPConfig_->retryCount; return true; } -char emsMsg[EMS_MSG_SIZE]; +char eventMsg[MAX_EVENT_MSG_SIZE]; if (self.host_->LDAPConfig_->retryCount > 0) - sprintf(emsMsg,"Unable to establish initial LDAP connection after %d retries, error %d\n", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Unable to establish initial LDAP connection after %d retries, error %d\n", self.host_->LDAPConfig_->retryCount,retCode); else - sprintf(emsMsg,"Unable to establish initial LDAP connection, error %d\n", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Unable to establish initial LDAP connection, error %d\n", retCode); - LOG_AUTH_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,emsMsg); + INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return false; @@ -1011,7 +1006,7 @@ LDSearchStatus LDAPConfigNode::lookupUser( { int rc = 0; -char emsMsg[EMS_MSG_SIZE]; +char eventMsg[MAX_EVENT_MSG_SIZE]; LDSearchStatus searchStatus = searchUser(self,inputName,userDN); @@ -1062,12 +1057,12 @@ int retry_count = self.host_->LDAPConfig_->retryCount; // if (self.host_->LDAPConfig_->retryCount > 0) - sprintf(emsMsg, "Failed to search for LDAP user %s after %d retries\n", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to search for LDAP user %s after %d retries\n", inputName,self.host_->LDAPConfig_->retryCount); else - sprintf(emsMsg, "Failed to search for LDAP user %s\n",inputName); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to search for LDAP user %s\n",inputName); - LOG_AUTH_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,emsMsg); + INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LDSearchResourceFailure; } @@ -1105,24 +1100,24 @@ static void addExcludedHostName( { -char emsMsg[EMS_MSG_SIZE]; + char eventMsg[MAX_EVENT_MSG_SIZE]; -// If the size of the excluded host list is being limited, clear out -// older excluded hosts to make room for the newest entry. + // If the size of the excluded host list is being limited, clear out + // older excluded hosts to make room for the newest entry. if (self.host_->LDAPConfig_->maxExcludeListSize > 0) while (self.host_->excludedHostNames.size() >= self.host_->LDAPConfig_->maxExcludeListSize) { - sprintf(emsMsg,"Exclude list full, LDAP server %s removed from exclude list\n", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Exclude list full, LDAP server %s removed from exclude list\n", self.host_->excludedHostNames[0].c_str()); - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,emsMsg); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); self.host_->excludedHostNames.erase(self.host_->excludedHostNames.begin()); } self.host_->excludedHostNames.push_back(hostName); - sprintf(emsMsg,"LDAP server %s added to exclude list\n",hostName); - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,emsMsg); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP server %s added to exclude list\n",hostName); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); } //************************ End of addExcludedHostName ************************** @@ -1179,7 +1174,7 @@ int rc, msgid, err; struct timeval timeout; LDAP *ld; LDAPMessage *result; -char emsMsg[EMS_MSG_SIZE]; +char eventMsg[MAX_EVENT_MSG_SIZE]; int parserc; LDAPControl **psrvctrls = NULL; @@ -1193,7 +1188,7 @@ bool isInitialized = reconnect; { if (!selfCheck(self,isInitialized)) { - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in bindUser"); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in bindUser"); return LDAuthResourceFailure; } @@ -1217,17 +1212,17 @@ bool isInitialized = reconnect; LD_Status status = initConnection(self,NULL,true); if (status != LD_STATUS_OK) { - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"LDAP Auth Error in bindUser; unable to connect to server"); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"LDAP Auth Error in bindUser; unable to connect to server"); return LDAuthResourceFailure; } reconnect = false; continue; } - sprintf(emsMsg, "LDAP Auth Error in bindUser; error code: %ld, ", (long) LDAPError); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP Auth Error in bindUser; error code: %ld, ", (long) LDAPError); errorTextString = ldap_err2string(LDAPError); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg,"\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg,"\n"); + INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); return LDAuthResourceFailure; // LCOV_EXCL_STOP } @@ -1248,7 +1243,7 @@ bool isInitialized = reconnect; if (status != LD_STATUS_OK) { // LCOV_EXCL_START - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"LDAP Auth Error in bindUser; unable to connect to server"); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"LDAP Auth Error in bindUser; unable to connect to server"); return LDAuthResourceFailure; // LCOV_EXCL_STOP } @@ -1256,11 +1251,11 @@ bool isInitialized = reconnect; continue; } ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err); - sprintf(emsMsg, "LDAP Auth Error in bindUser; error code: %ld, ", (long)err); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP Auth Error in bindUser; error code: %ld, ", (long)err); errorTextString = ldap_err2string(err); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg, "\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg, "\n"); + INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); LDAPError = err; return LDAuthResourceFailure; } @@ -1274,13 +1269,13 @@ bool isInitialized = reconnect; char *p = ldap_err2string(parserc); if (p != NULL) { - strcpy(emsMsg, "LDAP Auth Error in bindUser; Failed to get bind result: "); - strncat(emsMsg, p, (EMS_MSG_SIZE - (strlen(emsMsg)+4)) ); - strcat(emsMsg, "\n"); + strcpy(eventMsg, "LDAP Auth Error in bindUser; Failed to get bind result: "); + strncat(eventMsg, p, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4)) ); + strcat(eventMsg, "\n"); } else - strcpy(emsMsg, "LDAP Auth Error in bindUser; Failed to get bind result.\n"); - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,emsMsg); + strcpy(eventMsg, "LDAP Auth Error in bindUser; Failed to get bind result.\n"); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); LDAPError = parserc; return LDAuthResourceFailure; // LCOV_EXCL_STOP @@ -1341,11 +1336,11 @@ bool isInitialized = reconnect; break; default: // LCOV_EXCL_START - sprintf(emsMsg, "LDAP Auth Error in bindUser; error code: %ld, ", (long)rc); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP Auth Error in bindUser; error code: %ld, ", (long)rc); errorTextString = ldap_err2string(rc); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg, "\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg, "\n"); + INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); LDAPError = rc; return LDAuthResourceFailure; break; @@ -1511,7 +1506,7 @@ static LD_Status connectToURL( int version; int debug = 0; int rc; -char emsMsg[EMS_MSG_SIZE]; +char eventMsg[MAX_EVENT_MSG_SIZE]; char *errorTextString; LDAP *ld = NULL; @@ -1522,11 +1517,11 @@ struct timeval tv; if (rc != LDAP_SUCCESS) { // LCOV_EXCL_START - sprintf(emsMsg, "ldap_initialize failed for LDAP server %s. Error: %d, ",url.lud_host, rc); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "ldap_initialize failed for LDAP server %s. Error: %d, ",url.lud_host, rc); errorTextString = ldap_err2string(rc); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg, "\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg, "\n"); + INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; // LCOV_EXCL_STOP } @@ -1534,8 +1529,8 @@ struct timeval tv; if (ld == NULL) { // LCOV_EXCL_START - sprintf(emsMsg, "Failed to initialize the connection to LDAP server %s. Error: ld is NULL", url.lud_host); - LOG_AUTH_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,emsMsg); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to initialize the connection to LDAP server %s. Error: ld is NULL", url.lud_host); + INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; // LCOV_EXCL_STOP } @@ -1611,11 +1606,11 @@ int ldapderef = LDAP_DEREF_ALWAYS; rc = ldap_set_option(ld,LDAP_OPT_X_TLS_REQUIRE_CERT,&demand); if (rc != LDAP_SUCCESS) { - sprintf(emsMsg, "Require TLS certificate failed for LDAP server %s. Error: %d, ", url.lud_host, rc); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Require TLS certificate failed for LDAP server %s. Error: %d, ", url.lud_host, rc); errorTextString = ldap_err2string(rc); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg, "\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg, "\n"); + INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; } @@ -1623,11 +1618,11 @@ int ldapderef = LDAP_DEREF_ALWAYS; config.TLS_CACERTFilename.c_str()); if (rc != LDAP_SUCCESS) { - sprintf(emsMsg, "Set TLS certificate file failed for LDAP server %s. Error: %d, ", url.lud_host, rc); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Set TLS certificate file failed for LDAP server %s. Error: %d, ", url.lud_host, rc); errorTextString = ldap_err2string(rc); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg, "\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg, "\n"); + INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; } } @@ -1638,11 +1633,11 @@ int ldapderef = LDAP_DEREF_ALWAYS; rc = ldap_start_tls_s (ld, NULL, NULL); if (rc != LDAP_SUCCESS) { - sprintf(emsMsg, "StartTLS failed for LDAP server %s. Error: %d, ", url.lud_host, rc); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "StartTLS failed for LDAP server %s. Error: %d, ", url.lud_host, rc); errorTextString = ldap_err2string(rc); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg, "\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg, "\n"); + INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; } } @@ -1665,12 +1660,12 @@ LDAuthStatus authStatus; if (authStatus != LDAuthSuccessful) { // LCOV_EXCL_START - sprintf(emsMsg,"Initial bind failed for LDAP server %s. Error: %d, ", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Initial bind failed for LDAP server %s. Error: %d, ", url.lud_host,LDAPError); errorTextString = ldap_err2string(LDAPError); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg, "\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg, "\n"); + INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; // LCOV_EXCL_STOP } @@ -1688,11 +1683,11 @@ LDAuthStatus authStatus; if (authStatus != LDAuthSuccessful) { // LCOV_EXCL_START - sprintf(emsMsg, "Initial bind with search user failed for LDAP server %s. Error: %d, ", url.lud_host, LDAPError); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Initial bind with search user failed for LDAP server %s. Error: %d, ", url.lud_host, LDAPError); errorTextString = ldap_err2string(LDAPError); - strncat(emsMsg, errorTextString, (EMS_MSG_SIZE - (strlen(emsMsg)+4))); - strcat(emsMsg, "\n"); - LOG_AUTH_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,emsMsg); + strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); + strcat(eventMsg, "\n"); + INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; // LCOV_EXCL_STOP } @@ -1982,7 +1977,7 @@ inline static void logConfigFileError( { -char emsMsg[EMS_MSG_SIZE]; +char eventMsg[MAX_EVENT_MSG_SIZE]; switch (fileCode) { @@ -1991,52 +1986,52 @@ char emsMsg[EMS_MSG_SIZE]; break; case LDAPConfigFile_NoFileProvided: case LDAPConfigFile_FileNotFound: - sprintf(emsMsg, "****** .traf_authentication_config file not found\n"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** .traf_authentication_config file not found\n"); break; case LDAPConfigFile_BadAttributeName: - sprintf(emsMsg,"****** Unrecognized attribute in .traf_authentication_config configuration file. Line %d %s", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Unrecognized attribute in .traf_authentication_config configuration file. Line %d %s", lastLineNumber,lastLine.c_str()); break; case LDAPConfigFile_MissingValue: - sprintf(emsMsg,"****** Missing required value in .traf_authentication_config configuration file. Line %d %s", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Missing required value in .traf_authentication_config configuration file. Line %d %s", lastLineNumber,lastLine.c_str()); break; case LDAPConfigFile_ValueOutofRange: - sprintf(emsMsg,"****** Value out of range in .traf_authentication_config configuration file. Line %d %s", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Value out of range in .traf_authentication_config configuration file. Line %d %s", lastLineNumber,lastLine.c_str()); break; case LDAPConfigFile_CantOpenFile: - sprintf(emsMsg,"****** Unable to open .traf_authentication_config configuration file"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Unable to open .traf_authentication_config configuration file"); break; case LDAPConfigFile_CantReadFile: - sprintf(emsMsg,"****** Unable to read .traf_authentication_config configuration file"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Unable to read .traf_authentication_config configuration file"); break; case LDAPConfigFile_MissingCACERTFilename: - sprintf(emsMsg,"****** TLS requested but no TLS CACERTFilename was provided"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** TLS requested but no TLS CACERTFilename was provided"); break; case LDAPConfigFile_MissingHostName: - sprintf(emsMsg,"****** Missing host name in .traf_authentication_config"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Missing host name in .traf_authentication_config"); break; case LDAPConfigFile_MissingUniqueIdentifier: - sprintf(emsMsg,"****** Missing unique identifier in .traf_authentication_config"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Missing unique identifier in .traf_authentication_config"); break; case LDAPConfigFile_MissingSection: - sprintf(emsMsg,"****** Missing directory server configuration in .traf_authentication_config"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Missing directory server configuration in .traf_authentication_config"); break; case LDAPConfigFile_ParseError: - sprintf(emsMsg,"****** Internal error parsing .traf_authentication_config"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Internal error parsing .traf_authentication_config"); break; case LDAPConfigFile_CantOpenLDAPRC: - sprintf(emsMsg,"****** Unable to open .ldaprc to determine TLS CACERTFilename"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Unable to open .ldaprc to determine TLS CACERTFilename"); break; case LDAPConfigFile_MissingLDAPRC: - sprintf(emsMsg,"****** Missing .ldaprc and TLS_CACERTFilename not provided; cannot determine TLS CACERT filename"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Missing .ldaprc and TLS_CACERTFilename not provided; cannot determine TLS CACERT filename"); break; default: - sprintf(emsMsg,"****** Error parsing .traf_authentication_config configuration file"); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Error parsing .traf_authentication_config configuration file"); } - LOG_AUTH_EVENT(DBS_AUTH_CONFIG,emsMsg); + INSERT_EVENT(DBS_AUTH_CONFIG,eventMsg); } //************************** End of logConfigFileError ************************* @@ -2301,7 +2296,7 @@ char *attrs[3]; char *attr, **vals; BerElement *ptr = 0; char createTimestamp[16]; -char emsMsg[EMS_MSG_SIZE]; +char eventMsg[MAX_EVENT_MSG_SIZE]; // Use "createTimestamp" as our "unique ID" for the user on the LDAP server. strcpy(createTimestamp, "createTimestamp"); @@ -2339,7 +2334,7 @@ int reconnect = 1; { if (!selfCheck(self,true)) { - LOG_AUTH_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in searchUserByDN"); + INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in searchUserByDN"); return LDSearchResourceFailure; } @@ -2380,8 +2375,8 @@ int reconnect = 1; // resource failure error so we will retry per configuration settings. if (status != LD_STATUS_OK) { - sprintf(emsMsg, "LDAP search error. Unable to connect to server\n"); - LOG_AUTH_EVENT(DBS_LDAP_SEARCH_ERROR,emsMsg); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP search error. Unable to connect to server\n"); + INSERT_EVENT(DBS_LDAP_SEARCH_ERROR,eventMsg); return LDSearchResourceFailure; } reconnect--; @@ -2391,9 +2386,9 @@ int reconnect = 1; // For all other search errors, report an error and return a resource // failure (LDAP server or network problem) so we will retry per // configuration settings. - sprintf(emsMsg, "LDAP search error. Error code: %d, %s\n", + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP search error. Error code: %d, %s\n", rc, ldap_err2string(rc)); - LOG_AUTH_EVENT(DBS_LDAP_SEARCH_ERROR,emsMsg); + INSERT_EVENT(DBS_LDAP_SEARCH_ERROR,eventMsg); return LDSearchResourceFailure; } @@ -2431,8 +2426,8 @@ int numberFound = ldap_count_entries(ld,res); ldap_msgfree(res); // log error message - sprintf(emsMsg, "LDAP search error. Attribute %s does not exist in the entry %s", attrs[0], userDN.c_str()); - LOG_AUTH_EVENT(DBS_LDAP_SEARCH_ERROR,emsMsg); + snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP search error. Attribute %s does not exist in the entry %s", attrs[0], userDN.c_str()); + INSERT_EVENT(DBS_LDAP_SEARCH_ERROR,eventMsg); return LDSearchResourceFailure; } diff --git a/core/dbsecurity/macros.gmk b/core/dbsecurity/macros.gmk index 63a97b3167..948a86ade3 100644 --- a/core/dbsecurity/macros.gmk +++ b/core/dbsecurity/macros.gmk @@ -43,7 +43,13 @@ CXXFLAGS += $(DEFINES) $(CXXWARN) -std=c++0x $(GCCMODEXX) # Modules in current directory -$(OUTDIR)/%.o: src/%.cpp +$(OUTDIR)/%.o: src/%.cpp +# echo " *****FLAGS::: $(CXX) *****" + @if [ -d "$(OUTDIR)" ]; then x=1; else mkdir -p "$(OUTDIR)"; fi + $(CXX) $(CXXFLAGS) $(INCLUDES) -c -fPIC -o $@ $< + +# Modules in logging directory +$(OUTDIR)/%.o: $(MY_SQROOT)/commonLogger/CommonLogger.cpp # echo " *****FLAGS::: $(CXX) *****" @if [ -d "$(OUTDIR)" ]; then x=1; else mkdir -p "$(OUTDIR)"; fi $(CXX) $(CXXFLAGS) $(INCLUDES) -c -fPIC -o $@ $< diff --git a/core/sqf/conf/log4cxx.trafodion.auth.config b/core/sqf/conf/log4cxx.trafodion.auth.config new file mode 100644 index 0000000000..34f1dbdbc2 --- /dev/null +++ b/core/sqf/conf/log4cxx.trafodion.auth.config @@ -0,0 +1,49 @@ +# +# @@@ START COPYRIGHT @@@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# @@@ END COPYRIGHT @@@ +# + +# Define some default values that can be overridden by system properties +trafodion.root.logger=INFO, authAppender +trafodion.log.dir=${MY_SQROOT}/logs +trafodion.log.filename.suffix=${TRAFODION_LOG_FILENAME_SUFFIX} + +# Define the root logger to the system property "trafodion.root.logger". +log4j.rootLogger=${trafodion.root.logger} + +# Logging Threshold +log4j.threshhold=ALL + +# +# Daily Rolling File Appender +# +log4j.appender.authAppender=org.apache.log4j.RollingFileAppender +log4j.appender.authAppender.file=${trafodion.log.dir}/dbsecurity${trafodion.log.filename.suffix} +log4j.appender.authAppender.maxFileSize=100000000 +log4j.appender.authAppender.maxBackupIndex=1 +log4j.appender.authAppender.addPid=false +log4j.appender.authAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.authAppender.layout.ConversionPattern=%d, %p, %c, %m%n +log4j.appender.authAppender.Append=true + +# Custom Logging levels +log4j.logger.AUTH.LDAP=ERROR, authAppender + diff --git a/core/sqf/export/include/common/evl_sqlog_eventnum.h b/core/sqf/export/include/common/evl_sqlog_eventnum.h index 3130e15577..0d7d644c69 100644 --- a/core/sqf/export/include/common/evl_sqlog_eventnum.h +++ b/core/sqf/export/include/common/evl_sqlog_eventnum.h @@ -1404,7 +1404,8 @@ enum DB_SECURITY_EVENTID // dbaudit Errors DBS_AMQP_ERROR = 119003001, - // dbsevents Errors + // dbaudit info + DBS_AUTHENTICATION_ATTEMPT = 119004001, // SQL Errors DBS_SQL_ERROR = 119005001 From 3e05c90de214174e5735aadcb0ea1232355ababf Mon Sep 17 00:00:00 2001 From: Roberta Marton Date: Tue, 20 Sep 2016 00:04:40 +0000 Subject: [PATCH 2/2] [TRAFODION-1794]: Log authentication Information Made changes suggested by previous delivery --- core/conn/odbc/src/odbc/nsksrvrcore/Makefile | 2 +- core/dbsecurity/auth/Makefile | 2 - core/dbsecurity/auth/inc/auth.h | 11 - core/dbsecurity/auth/inc/authEvents.h | 28 +- core/dbsecurity/auth/inc/dbUserAuth.h | 2 + core/dbsecurity/auth/inc/ldapconfignode.h | 46 ++- core/dbsecurity/auth/src/authEvents.cpp | 52 +++- core/dbsecurity/auth/src/dbUserAuth.cpp | 100 ++---- core/dbsecurity/auth/src/ldapcheck.cpp | 301 ++++++++++--------- core/dbsecurity/auth/src/ldapconfignode.cpp | 260 ++++++++++------ 10 files changed, 457 insertions(+), 347 deletions(-) diff --git a/core/conn/odbc/src/odbc/nsksrvrcore/Makefile b/core/conn/odbc/src/odbc/nsksrvrcore/Makefile index 5490cbe9df..53cb1fb3fe 100644 --- a/core/conn/odbc/src/odbc/nsksrvrcore/Makefile +++ b/core/conn/odbc/src/odbc/nsksrvrcore/Makefile @@ -64,7 +64,7 @@ OBJS = $(OUTDIR)/CommonDiags.o \ $(OUTDIR)/srvrothers.o \ $(OUTDIR)/libmxocore_version.o -INCLUDES = -I. -I../Common -I../EventMsgs -I../SrvrMsg -I../dependencies/include -I../dependencies/linux -I../Krypton/generated_incs -I$(SQ_HOME)/export/include/sql -I$(SQ_HOME)/inc/tmf_tipapi -I$(SQ_HOME)/inc -I$(SQ_HOME)/export/include -I$(SQ_HOME)/sql/nq_w/common -I../OssCfgCl/src -I../CmdCfgDll -I$(PROTOBUFS_INC) -I$(SQ_HOME)/../sql/cli -I$(SQ_HOME)/../dbsecurity/cert/inc -I$(SQ_HOME)/../dbsecurity/auth/inc -I$(SQ_HOME)/../mpi/src/include/intern +INCLUDES = -I. -I../Common -I../EventMsgs -I../SrvrMsg -I../dependencies/include -I../dependencies/linux -I../Krypton/generated_incs -I$(SQ_HOME)/export/include/sql -I$(SQ_HOME)/inc/tmf_tipapi -I$(SQ_HOME)/inc -I$(SQ_HOME)/export/include -I$(SQ_HOME)/sql/nq_w/common -I../OssCfgCl/src -I../CmdCfgDll -I$(PROTOBUFS_INC) -I$(SQ_HOME)/../sql/cli -I$(SQ_HOME)/commonLogger -I$(SQ_HOME)/../dbsecurity/cert/inc -I$(SQ_HOME)/../dbsecurity/auth/inc -I$(SQ_HOME)/../mpi/src/include/intern DEFINES = -DNA_LINUX -DSIZEOF_LONG_INT=4 -DUSE_NEW_PHANDLE -DSQ_GUARDIAN_CALL -D_M_DG -DINC_QPID_EVENT -w diff --git a/core/dbsecurity/auth/Makefile b/core/dbsecurity/auth/Makefile index acb26f6f59..9bd67e67d9 100644 --- a/core/dbsecurity/auth/Makefile +++ b/core/dbsecurity/auth/Makefile @@ -74,8 +74,6 @@ INCLUDES = -I. -I./inc -I ../shared/inc \ LINK_OPTIONS = -L$(LIBEXPDIR) -lldap -lssl -llber -llog4cxx LINK_OPTIONS += $(LNK_FLGS) -COMMON_LIBS = -ltdm_sqlcli -larkcmp_dll - $(LIBEXPDIR)/libsqauth.so: $(OBJS) $(CXX) -fPIC $(DBG_FLAGS) -shared $(GCCMODEXX) -o $@ $(INCLUDES) $(LINK_OPTIONS) $(OBJS) diff --git a/core/dbsecurity/auth/inc/auth.h b/core/dbsecurity/auth/inc/auth.h index 68d9b42300..2b51371031 100644 --- a/core/dbsecurity/auth/inc/auth.h +++ b/core/dbsecurity/auth/inc/auth.h @@ -49,17 +49,6 @@ enum UA_Status{ UA_STATUS_PARAM5 = 5 }; -enum AUTH_OUTCOME{ - AUTH_OK = 0, - AUTH_NOT_REGISTERED = 1, - AUTH_MD_NOT_AVAILABLE = 2, - AUTH_USER_INVALID = 3, - AUTH_TYPE_INCORRECT = 4, - AUTH_NO_PASSWORD = 5, - AUTH_REJECTED = 6, - AUTH_FAILED = 7 -}; - // Define a struct to populate the fields needed by authentication audit typedef struct client_info diff --git a/core/dbsecurity/auth/inc/authEvents.h b/core/dbsecurity/auth/inc/authEvents.h index 8c4cefaba4..cd53ea5bf0 100644 --- a/core/dbsecurity/auth/inc/authEvents.h +++ b/core/dbsecurity/auth/inc/authEvents.h @@ -31,10 +31,28 @@ // For DBSecurity don't believe any messages will be more than 1M #define MAX_EVENT_MSG_SIZE 1024 +// Different outcomes can be returned when authenticating the user. +// AUTH_OUTCOME is a status for each of these outcomes. +// getAuthOutcome translates the status into text form. +enum AUTH_OUTCOME{ + AUTH_OK = 0, + AUTH_REJECTED = 1, + AUTH_FAILED = 2, + AUTH_NOT_REGISTERED = 3, + AUTH_MD_NOT_AVAILABLE = 4, + AUTH_USER_INVALID = 5, + AUTH_TYPE_INCORRECT = 6, + AUTH_NO_PASSWORD = 7, +}; + +std::string getAuthOutcome(AUTH_OUTCOME outcome); + // The ported code had the caller sending in the filename and line number // for certain events. This has not been implemented at this time. -struct AuthEvent +class AuthEvent { + private: + DB_SECURITY_EVENTID eventID_; std::string eventText_; logLevel severity_; @@ -42,6 +60,8 @@ struct AuthEvent int32_t lineNumber_; std::string callerName_; + public: + AuthEvent () : eventID_ (DBS_GENERIC_ERROR), severity_ (LL_INFO), @@ -59,7 +79,7 @@ struct AuthEvent lineNumber_(0), callerName_ ("??") {} - + DB_SECURITY_EVENTID getEventID () { return eventID_; } logLevel getSeverity() { return severity_; } int32_t getLineNum() { return lineNumber_; } @@ -77,11 +97,9 @@ struct AuthEvent }; -extern std::vector authEvents; - void authInitEventLog(); - void insertAuthEvent( + std::vector & authEvents, DB_SECURITY_EVENTID eventID, const char * eventText, logLevel severity); diff --git a/core/dbsecurity/auth/inc/dbUserAuth.h b/core/dbsecurity/auth/inc/dbUserAuth.h index ba48216d94..db0142b225 100644 --- a/core/dbsecurity/auth/inc/dbUserAuth.h +++ b/core/dbsecurity/auth/inc/dbUserAuth.h @@ -24,6 +24,7 @@ #include #include #include "auth.h" +#include "authEvents.h" enum AuthConfigType { @@ -36,6 +37,7 @@ enum AuthConfigType enum LDAPAuthResultEnum { AuthResult_Successful, // User was authenticated on LDAP server + AuthResult_NotFound, // User was not found in search AuthResult_Rejected, // User was rejected by LDAP server AuthResult_ResourceError}; // An error prevented authentication diff --git a/core/dbsecurity/auth/inc/ldapconfignode.h b/core/dbsecurity/auth/inc/ldapconfignode.h index 0d724af4c8..3a7eda9534 100644 --- a/core/dbsecurity/auth/inc/ldapconfignode.h +++ b/core/dbsecurity/auth/inc/ldapconfignode.h @@ -23,6 +23,7 @@ // @@@ END COPYRIGHT @@@ //****************************************************************************** #include +#include "authEvents.h" using namespace std; #pragma page "Class LDAPConfigNode" @@ -88,50 +89,69 @@ enum LDAPConfigType }; static void ClearRetryCounts(); + static void CloseConnection(); static void FreeInstance( LDAPConfigType configType, LDAPConnectionType connectionType); + static size_t GetBindRetryCount(); + static LDAPConfigNode *GetLDAPConnection( - LDAPConfigType configType, - LDAPConnectionType connectionType, - char * hostName = NULL); + std::vector & authEvents, + LDAPConfigType configType, + LDAPConnectionType connectionType, + char * hostName = NULL); + static LDAPConfigNode * GetInstance( - LDAPConfigType configType, - LDAPConnectionType connectionType); + std::vector & authEvents, + LDAPConfigType configType, + LDAPConnectionType connectionType); + static size_t GetSearchRetryCount(); - static void Refresh(); + + static void Refresh(std::vector & authEvents); + static const char * TestGetConfigFilename(); LDAuthStatus authenticateUser( - const char *username, - const char *password); + std::vector & authEvents, + const char * username, + const char * password); LDAPConfigType getConfigType() const; LDSearchStatus lookupUser( - const char *inputName, - string &userDN); + std::vector & authEvents, + const char * inputName, + string & userDN); private: ConfigNodeContents &self; LDAPConfigNode(); + LDAPConfigNode( LDAPConfigType configType, LDAPConnectionType connectionType); LDAPConfigNode( const LDAPConfigNode & other ); + LDAPConfigNode & operator = ( const LDAPConfigNode & other ); + virtual ~LDAPConfigNode(); - static bool GetConfiguration(LDAPConfigType &configType); + + static bool GetConfiguration( + std::vector & authEvents, + LDAPConfigType & configType); + static void GetDefaultConfiguration(); - bool initialize(char * hostName); - + bool initialize( + std::vector & authEvents, + char * hostName); }; #endif diff --git a/core/dbsecurity/auth/src/authEvents.cpp b/core/dbsecurity/auth/src/authEvents.cpp index 19cd90cd52..24cbcd1ba0 100644 --- a/core/dbsecurity/auth/src/authEvents.cpp +++ b/core/dbsecurity/auth/src/authEvents.cpp @@ -25,11 +25,11 @@ #include #include #include -#include "seabed/ms.h" -#include "seabed/fserr.h" + +class AuthEvent; static std::string AUTH_COMPONENT = "DBSECURITY"; -std::vector authEvents; + // **************************************************************************** // function: insertAuthEvent @@ -42,12 +42,13 @@ std::vector authEvents; // severity - severity of the event // **************************************************************************** void insertAuthEvent( + std::vector & authEvents, DB_SECURITY_EVENTID eventID, const char * eventText, logLevel severity) { AuthEvent authEvent(eventID, - AuthEvent::formatEventText(eventText), + eventText, severity); authEvents.push_back(authEvent); } @@ -83,6 +84,47 @@ void authInitEventLog() CommonLogger::instance().initLog4cxx("log4cxx.trafodion.auth.config",log_name_suffix); } +// **************************************************************************** +// function getAuthOutcome +// +// Returns a text representation of the error from the AUTH_OUTCOME enum +// +// **************************************************************************** +std::string getAuthOutcome(AUTH_OUTCOME outcome) +{ + std::string outcomeDesc; + switch (outcome) + { + case AUTH_OK: + outcomeDesc = "Authentication successful"; + break; + case AUTH_NOT_REGISTERED: + outcomeDesc = "User not registered"; + break; + case AUTH_MD_NOT_AVAILABLE: + outcomeDesc = "Unexpected error occurred looking up user in database"; + break; + case AUTH_USER_INVALID: + outcomeDesc = "User is not valid"; + break; + case AUTH_TYPE_INCORRECT: + outcomeDesc = "Unexpected authorization type detected"; + break; + case AUTH_NO_PASSWORD: + outcomeDesc = "Invalid password"; + break; + case AUTH_REJECTED: + outcomeDesc = "Invalid username or password"; + break; + case AUTH_FAILED: + outcomeDesc = "Unexpected error returned from LDAP"; + break; + default: + outcomeDesc = "Unexpected error occurred"; + } + return outcomeDesc; +} + // **************************************************************************** // method: AuthEvent::formatEventText // @@ -123,7 +165,7 @@ void AuthEvent::logAuthEvent() // Log4cxx logging char buf[MAX_EVENT_MSG_SIZE]; - snprintf(buf, MAX_EVENT_MSG_SIZE, "Node Number: %u, CPU: %u, PIN: %u ,,,, Message: %s", + snprintf(buf, MAX_EVENT_MSG_SIZE, "Node Number: %u, CPU: %u, PIN: %u ,,,, %s", my_nid, my_cpu, my_pid, eventText_.c_str()); // strip off final new line before logging diff --git a/core/dbsecurity/auth/src/dbUserAuth.cpp b/core/dbsecurity/auth/src/dbUserAuth.cpp index 3ab2dbedd7..80cf6c0a75 100644 --- a/core/dbsecurity/auth/src/dbUserAuth.cpp +++ b/core/dbsecurity/auth/src/dbUserAuth.cpp @@ -123,7 +123,7 @@ static int32_t fetchFromAUTHSTable( int64_t & redefTime); -static void logAuthenticationErrors(); +static void logAuthenticationErrors(std::vector & authEvents); static void logAuthenticationOutcome( const string & external_user_name, @@ -182,13 +182,15 @@ class BlackBox class DBUserAuthContents { public: - BlackBox bb; - int nodeID; + BlackBox bb; + int nodeID; + std::vector authEvents; int bypassAuthentication( Token & token, AUTHENTICATION_INFO & authenticationInfo); + std::vector &getAuthEvents() { return authEvents; } void deserialize(Token &token); void reset(); @@ -444,7 +446,8 @@ DBUserAuth::CheckUserResult DBUserAuth::CheckExternalUsernameDefined( return CheckUserResult_UserExists; #else -char *authEnv; + char *authEnv; + std::vector authEvents; authEnv = getenv("TRAFODION_ENABLE_AUTHENTICATION"); if (authEnv == NULL || strcmp(authEnv,"YES") != 0) @@ -453,10 +456,10 @@ char *authEnv; return UserExists; } -string userDN = ""; // User DN, used to bind to LDAP serer -LDAPConfigNode *searchNode; + string userDN = ""; // User DN, used to bind to LDAP serer + LDAPConfigNode *searchNode; -LDAPConfigNode::LDAPConfigType configType = LDAPConfigNode::UnknownConfiguration; + LDAPConfigNode::LDAPConfigType configType = LDAPConfigNode::UnknownConfiguration; switch (configurationOrdinal) { @@ -470,21 +473,21 @@ LDAPConfigNode::LDAPConfigType configType = LDAPConfigNode::UnknownConfiguration configType = LDAPConfigNode::UnknownConfiguration; } - searchNode = LDAPConfigNode::GetLDAPConnection(configType,SearchConnection); + searchNode = LDAPConfigNode::GetLDAPConnection(authEvents,configType,SearchConnection); if (searchNode == NULL) return ErrorDuringCheck; -LDSearchStatus searchStatus = searchNode->lookupUser(externalUsername,userDN); + LDSearchStatus searchStatus = searchNode->lookupUser(authEvents,externalUsername,userDN); if (searchStatus == LDSearchNotFound) return UserDoesNotExist; -// didn't get "found" or "not found", so we have problems! + // didn't get "found" or "not found", so we have problems! if (searchStatus != LDSearchFound) return ErrorDuringCheck; -// External username was found. But where? + // External username was found. But where? switch (searchNode->getConfigType()) { case LDAPConfigNode::UnknownConfiguration: @@ -1242,7 +1245,7 @@ static void authenticateUser( usersInfo.sessionUserID,clientInfo, (authStatus = LDAuthRejected) ? AUTH_REJECTED : AUTH_FAILED); // Log any events generated - logAuthenticationErrors(); + logAuthenticationErrors(self.authEvents); } //************************** End of authenticateUser *************************** @@ -1336,7 +1339,7 @@ static LDAuthStatus executeLDAPAuthentication( { LDAPConfigNode::ClearRetryCounts(); - authEvents.clear(); + self.getAuthEvents().clear(); // // First get a search connection for the specified configuration. @@ -1345,7 +1348,7 @@ static LDAuthStatus executeLDAPAuthentication( // int64_t startTime = JULIANTIMESTAMP(); - LDAPConfigNode *searchNode = LDAPConfigNode::GetLDAPConnection(configType, + LDAPConfigNode *searchNode = LDAPConfigNode::GetLDAPConnection(self.authEvents,configType, SearchConnection); performanceInfo.searchConnectionTime = JULIANTIMESTAMP() - startTime; @@ -1358,7 +1361,7 @@ static LDAuthStatus executeLDAPAuthentication( self.bb.errorDetail = UA_STATUS_ERR_SYSTEM; snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to get LDAP connection for user %s",username); - insertAuthEvent(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); + insertAuthEvent(self.authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); return LDAuthResourceFailure; } @@ -1367,7 +1370,7 @@ static LDAuthStatus executeLDAPAuthentication( startTime = JULIANTIMESTAMP(); - LDSearchStatus searchStatus = searchNode->lookupUser(username,userDN); + LDSearchStatus searchStatus = searchNode->lookupUser(self.authEvents,username,userDN); performanceInfo.searchTime = JULIANTIMESTAMP() - startTime; @@ -1377,7 +1380,7 @@ static LDAuthStatus executeLDAPAuthentication( self.bb.errorDetail = UA_STATUS_ERR_INVALID; snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed LDAP search for user %s",username); - insertAuthEvent(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); + insertAuthEvent(self.authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); return LDAuthRejected; } @@ -1388,7 +1391,7 @@ static LDAuthStatus executeLDAPAuthentication( self.bb.errorDetail = UA_STATUS_ERR_SYSTEM; snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed LDAP search for user %s",username); - insertAuthEvent(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); + insertAuthEvent(self.authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); return LDAuthResourceFailure; } @@ -1402,7 +1405,7 @@ static LDAuthStatus executeLDAPAuthentication( // startTime = JULIANTIMESTAMP(); - LDAPConfigNode *authNode = LDAPConfigNode::GetLDAPConnection(configType, + LDAPConfigNode *authNode = LDAPConfigNode::GetLDAPConnection(self.authEvents,configType, AuthenticationConnection); performanceInfo.authenticationConnectionTime = JULIANTIMESTAMP() - startTime; @@ -1413,7 +1416,7 @@ static LDAuthStatus executeLDAPAuthentication( self.bb.errorDetail = UA_STATUS_ERR_SYSTEM; snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed LDAP search on password for user %s",username); - insertAuthEvent(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); + insertAuthEvent(self.authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg, LL_ERROR); return LDAuthResourceFailure; } @@ -1422,7 +1425,7 @@ static LDAuthStatus executeLDAPAuthentication( // startTime = JULIANTIMESTAMP(); - LDAuthStatus authStatus = authNode->authenticateUser(userDN.c_str(),password); + LDAuthStatus authStatus = authNode->authenticateUser(self.authEvents,userDN.c_str(),password); performanceInfo.authenticationTime = JULIANTIMESTAMP() - startTime; @@ -1797,7 +1800,7 @@ size_t cacheCount = userCache.size(); // * Resource failures have already been inserted into authEvents structure * // * * // ***************************************************************************** -static void logAuthenticationErrors() +static void logAuthenticationErrors(std::vector &authEvents) { size_t errorCount = authEvents.size(); @@ -1847,62 +1850,25 @@ static void logAuthenticationOutcome( string internalUser("??"); if (user_id > 0) internalUser = internal_user_name; - logLevel severity = LL_INFO; + logLevel severity = (outcome == AUTH_FAILED) ? LL_ERROR : LL_INFO; // Currently this code has hard coded error messages in many places, this // need to be fixed in order to allow errors to be reported in different // languages. - string outcomeDesc; - switch (outcome) - { - case AUTH_OK: - outcomeDesc = "Authentication successful"; - severity = LL_INFO; - break; - case AUTH_NOT_REGISTERED: - outcomeDesc = "User not registered"; - break; - case AUTH_MD_NOT_AVAILABLE: - outcomeDesc = "Unexpected error occurred looking up user in database"; - severity = LL_INFO; - break; - case AUTH_USER_INVALID: - outcomeDesc = "User is not valid"; - severity = LL_INFO; - break; - case AUTH_TYPE_INCORRECT: - outcomeDesc = "Unexpected authorization type detected"; - severity = LL_INFO; - break; - case AUTH_NO_PASSWORD: - outcomeDesc = "Invalid password"; - severity = LL_INFO; - break; - case AUTH_REJECTED: - outcomeDesc = "Invalid username or password"; - severity = LL_INFO; - break; - case AUTH_FAILED: - outcomeDesc = "Unexpected error returned from LDAP"; - severity = LL_ERROR; - break; - default: - severity = LL_ERROR; - outcomeDesc = "Unexpected error occurred"; - } + string outcomeDesc = getAuthOutcome(outcome); char buf[MAX_EVENT_MSG_SIZE]; snprintf(buf, MAX_EVENT_MSG_SIZE, - "Outcome -> externalUser: %s, " - "databaseUser: %s, userID: %u, " - "clientName: %s, clientUserName: %s, " - "result: %d (%s)", + "Authentication request: externalUser %s, " + "databaseUser %s, userID %u, " + "clientName %s, clientUserName %s, " + "result %d (%s)", external_user_name.c_str(), internalUser.c_str(), user_id, clientInfo.clientName, clientInfo.clientUserName, - outcome, outcomeDesc.c_str()); + (int)outcome, outcomeDesc.c_str()); std::string msg(buf); - AuthEvent authEvent (DBS_AUTHENTICATION_ATTEMPT,msg, severity); + AuthEvent authEvent (DBS_AUTHENTICATION_ATTEMPT,msg,severity); authEvent.setCallerName("mxosrvr"); authEvent.logAuthEvent(); } diff --git a/core/dbsecurity/auth/src/ldapcheck.cpp b/core/dbsecurity/auth/src/ldapcheck.cpp index 3b965be69c..62f6d9255f 100755 --- a/core/dbsecurity/auth/src/ldapcheck.cpp +++ b/core/dbsecurity/auth/src/ldapcheck.cpp @@ -31,6 +31,7 @@ //****************************************************************************** #include "ldapconfignode.h" #include "authEvents.h" +#include "auth.h" #include #include @@ -53,12 +54,8 @@ enum Operation { Lookup = 3 }; -enum LDAPAuthResult { - AuthResult_Successful, // User was authenticated on LDAP server - AuthResult_Rejected, // User was rejected by LDAP server - AuthResult_ResourceError}; // An error prevented authentication - -LDAPAuthResult authenticateLDAPUser( +AUTH_OUTCOME authenticateLDAPUser( + std::vector & authEvents, const char * username, const char * password, LDAPConfigNode::LDAPConfigType configType, @@ -66,28 +63,34 @@ LDAPAuthResult authenticateLDAPUser( char * authHostName); void doAuthenticate( + std::vector & authEvents, const char * username, const char * password, LDAPConfigNode::LDAPConfigType configType, bool verbose); void doCanaryCheck( + std::vector & authEvents, const char * username, LDAPConfigNode::LDAPConfigType configType, bool verbose, - int & exitCode); + AUTH_OUTCOME exitCode); LDSearchStatus lookupLDAPUser( + std::vector & authEvents, const char * username, LDAPConfigNode::LDAPConfigType configType, char * searchHostName); void printTime(); -void reportAuthenticationErrors(bool displayErrors); +void reportResults( + Operation operation, + const std::vector & authEvents, + const char * username, + AUTH_OUTCOME outcome, + int verbose); -void reportRetries(Operation operation); - void setEcho(bool enable); // ***************************************************************************** @@ -101,6 +104,9 @@ void setEcho(bool enable); // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * const char * In * // * is the external username to be checked on the directory server. * // * * @@ -112,14 +118,15 @@ void setEcho(bool enable); // * * // ***************************************************************************** // * * -// * Returns: LDAPAuthResult * +// * Returns: AUTH_OUTCOME * // * * -// * AuthResult_Successful, -- User was authenticated on LDAP server * -// * AuthResult_Rejected, -- User was rejected by LDAP server * -// * AuthResult_ResourceError -- An error prevented authentication * +// * AUTH_OK -- User was authenticated on LDAP server * +// * AUTH_REJECTED -- User was rejected by LDAP server * +// * AUTH_FAILED -- An error prevented authentication * // * * // ***************************************************************************** -LDAPAuthResult authenticateLDAPUser( +AUTH_OUTCOME authenticateLDAPUser( + std::vector & authEvents, const char * username, const char * password, LDAPConfigNode::LDAPConfigType configType, @@ -128,50 +135,48 @@ LDAPAuthResult authenticateLDAPUser( { -string userDN = ""; // User DN, used to bind to LDAP serer -LDAPConfigNode *searchNode; + string userDN = ""; // User DN, used to bind to LDAP serer + LDAPConfigNode *searchNode; -// Zero len password is a non-auth bind in LDAP, so we treat it -// as a failed authorization. + // Zero len password is a non-auth bind in LDAP, so we treat it + // as a failed authorization. if (strlen(password) == 0) - return AuthResult_Rejected; + return AUTH_REJECTED; - searchNode = LDAPConfigNode::GetLDAPConnection(configType,SearchConnection, + searchNode = LDAPConfigNode::GetLDAPConnection(authEvents,configType,SearchConnection, searchHostName); if (searchNode == NULL) - return AuthResult_ResourceError; + return AUTH_FAILED; -LDSearchStatus searchStatus = searchNode->lookupUser(username,userDN); + LDSearchStatus searchStatus = searchNode->lookupUser(authEvents,username,userDN); if (searchStatus == LDSearchNotFound) - return AuthResult_Rejected; + return AUTH_REJECTED; if (searchStatus != LDSearchFound) - return AuthResult_ResourceError; + return AUTH_FAILED; -// User is defined there. But is their password correct? + // User is defined there. But is their password correct? -LDAPConfigNode *authNode = LDAPConfigNode::GetLDAPConnection(configType, - AuthenticationConnection, - authHostName); + LDAPConfigNode *authNode = LDAPConfigNode::GetLDAPConnection(authEvents,configType, + AuthenticationConnection, + authHostName); if (authNode == NULL) - return AuthResult_ResourceError; + return AUTH_FAILED; -// -// User exists, let's validate that non-blank password! -// + // User exists, let's validate that non-blank password! -LDAuthStatus authStatus = authNode->authenticateUser(userDN.c_str(),password); + LDAuthStatus authStatus = authNode->authenticateUser(authEvents,userDN.c_str(),password); if (authStatus == LDAuthSuccessful) - return AuthResult_Successful; + return AUTH_OK; if (authStatus == LDAuthRejected) - return AuthResult_Rejected; + return AUTH_REJECTED; - return AuthResult_ResourceError; + return AUTH_FAILED; } //************************ End of authenticateLDAPUser ************************* @@ -187,6 +192,9 @@ LDAuthStatus authStatus = authNode->authenticateUser(userDN.c_str(),password); // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * const char * In * // * is the external username to be checked on the directory server. * // * * @@ -201,6 +209,7 @@ LDAuthStatus authStatus = authNode->authenticateUser(userDN.c_str(),password); // * * // ***************************************************************************** void doAuthenticate( + std::vector & authEvents, const char * username, const char * password, LDAPConfigNode::LDAPConfigType configType, @@ -210,13 +219,13 @@ void doAuthenticate( LDAPConfigNode::ClearRetryCounts(); -char searchHostName[256]; -char authHostName[256]; + char searchHostName[256]; + char authHostName[256]; searchHostName[0] = authHostName[0] = 0; -LDAPAuthResult rc = authenticateLDAPUser(username,password,configType, - searchHostName,authHostName); + AUTH_OUTCOME rc = authenticateLDAPUser(authEvents,username,password,configType, + searchHostName,authHostName); if (verbose) { @@ -224,32 +233,14 @@ LDAPAuthResult rc = authenticateLDAPUser(username,password,configType, cout << "Auth host name: " << authHostName << endl; } -// -// How'd it go? In addition to a thumbs up/down, print diagnostics if -// requested. This matches production behavior; we log retries if -// successful, and we log all internal errors as well as number of retries -// if authentication failed due to a resource error. Resource errors include -// problems with the LDAP servers and parsing the LDAP connection configuration -// file (.traf_authentication_config). -// - if (rc == AuthResult_Rejected) - { - cout << "Invalid username or password" << endl; - return; - } - - if (rc == AuthResult_Successful) - cout << "Authentication successful" << endl; - else - cout << "Authentication failed: resource error" << endl; - - if (verbose) - { - reportRetries(Authenticate); - reportAuthenticationErrors(true); - } - else - reportAuthenticationErrors(false); + // How'd it go? In addition to a thumbs up/down, print diagnostics if + // requested. This matches production behavior; we log retries if + // successful, and we log all internal errors as well as number of retries + // if authentication failed due to a resource error. Resource errors include + // problems with the LDAP servers and parsing the LDAP connection configuration + // file (.traf_authentication_config). + + reportResults(Authenticate,authEvents,username,rc,verbose); } //*************************** End of doAuthenticate **************************** @@ -264,6 +255,9 @@ LDAPAuthResult rc = authenticateLDAPUser(username,password,configType, // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * const char * In * // * is the external username to be checked on the directory server. * // * * @@ -275,53 +269,41 @@ LDAPAuthResult rc = authenticateLDAPUser(username,password,configType, // * * // ***************************************************************************** void doCanaryCheck( + std::vector & authEvents, const char * username, LDAPConfigNode::LDAPConfigType configType, bool verbose, - int & exitCode) + AUTH_OUTCOME exitCode) { - exitCode = 0; - + exitCode = AUTH_OK; + char searchHostName[256]; searchHostName[0] = 0; - LDSearchStatus searchStatus = lookupLDAPUser(username,configType,searchHostName); + LDSearchStatus searchStatus = lookupLDAPUser(authEvents,username,configType,searchHostName); if (verbose) cout << "Search host name: " << searchHostName << endl; - if (authEvents.size() > 0) - exitCode = 1; - switch (searchStatus) { case LDSearchFound: - cout << "User " << username << " found" << endl; + exitCode = AUTH_OK; break; case LDSearchNotFound: - cout << "User " << username << " not found" << endl; - exitCode = 3; + exitCode = AUTH_REJECTED; break; case LDSearchResourceFailure: - cout << "Unable to lookup user due to LDAP errors" << endl; - exitCode = 2; + exitCode = AUTH_FAILED; break; default: - { - cout << "Internal error" << endl; - exitCode = 2; - } + exitCode = AUTH_FAILED; } - if (verbose) - { - reportRetries(Lookup); - reportAuthenticationErrors(true); - } - else - reportAuthenticationErrors(false); + + reportResults(Lookup,authEvents,username,exitCode,verbose); } //*************************** End of doCanaryCheck ***************************** @@ -338,6 +320,9 @@ void doCanaryCheck( // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * const char * In * // * is the external username to be checked on the directory server. * // * * @@ -355,6 +340,7 @@ void doCanaryCheck( // * * // ***************************************************************************** LDSearchStatus lookupLDAPUser( + std::vector & authEvents, const char * username, LDAPConfigNode::LDAPConfigType configType, char * searchHostName) @@ -363,7 +349,7 @@ LDSearchStatus lookupLDAPUser( LDAPConfigNode *searchNode; - searchNode = LDAPConfigNode::GetLDAPConnection(configType,SearchConnection, + searchNode = LDAPConfigNode::GetLDAPConnection(authEvents,configType,SearchConnection, searchHostName); if (searchNode == NULL) @@ -371,7 +357,7 @@ LDAPConfigNode *searchNode; string userDN = ""; - return searchNode->lookupUser(username,userDN); + return searchNode->lookupUser(authEvents,username,userDN); } //************************** End of lookupLDAPUser ***************************** @@ -422,83 +408,102 @@ void printUsage() -// ***************************************************************************** -// Function: reportAuthenticationErrors -// -// Logs and optionally displays any resource errors encountered during LDAP -// checking. -// ***************************************************************************** -void reportAuthenticationErrors(bool displayErrors) -{ - if (authEvents.size() > 0) - authInitEventLog(); - - // Walk the list of errors encountered during the attempt to authenticate - // the username, or username and password, and for each error, log the event - // ID and text. If displayErrors is true and logLevel is above the error - // level, send message to standard out. - std::string callerName ("ldapcheck"); - - for (size_t i = 0; i < authEvents.size(); i++) - { - AuthEvent authEvent = authEvents[i]; - authEvent.setCallerName(callerName); - authEvent.logAuthEvent(); - if (displayErrors) - cout << "ERROR: " << authEvent.getEventText().c_str() << endl; - } -} -//********************** End of reportAuthenticationErrors ********************* - - // ***************************************************************************** // * * -// * Function: reportRetries * +// * Function: reportResults * // * * -// * Displays any retries that occurred during an authentication or * -// * lookup operation. * +// * Logs and optionally displays any retries, errors, and outcome of an * +// * authentication or lookup operation. * // * * // ***************************************************************************** -void reportRetries(Operation operation) +void reportResults( + Operation operation, + const std::vector & authEvents, + const char * username, + AUTH_OUTCOME outcome, + int verbose) { -size_t bindRetryCount = LDAPConfigNode::GetBindRetryCount(); -size_t searchRetryCount = LDAPConfigNode::GetSearchRetryCount(); + std::string msg; -// If there were no retries, there is nothing to report. - if (bindRetryCount == 0 && searchRetryCount == 0) - return; + // Report any retries + size_t bindRetryCount = LDAPConfigNode::GetBindRetryCount(); + size_t searchRetryCount = LDAPConfigNode::GetSearchRetryCount(); -char operationString[20]; + char operationString[20]; if (operation == Authenticate) strcpy(operationString,"Authentication"); else strcpy(operationString,"Lookup"); -// Log if the search (name lookup) operation had to be retried. + + // Log and optionally display event for: + // search (name lookup) operation that was retried if (searchRetryCount > 0) { char searchRetryMessage[5100]; sprintf(searchRetryMessage,"%s required %d search retries. ", operationString,searchRetryCount); - cout << searchRetryMessage << endl; + msg = searchRetryMessage; + AuthEvent authEvent (DBS_AUTH_RETRY_SEARCH, msg, LL_INFO); + authEvent.setCallerName("ldapcheck"); + authEvent.logAuthEvent(); + if (verbose) + cout << searchRetryMessage << endl; } -// Log if the bind (password authentication) operation had to be retried. + // Log and optionally display event for: + // any bind (password authentication) operation that was retried if (bindRetryCount > 0) { char bindRetryMessage[5100]; sprintf(bindRetryMessage,"%s required %d bind retries. ", operationString,bindRetryCount); - cout << bindRetryMessage << endl; + msg = bindRetryMessage; + AuthEvent authEvent (DBS_AUTH_RETRY_BIND, msg, LL_INFO); + authEvent.setCallerName("ldapcheck"); + authEvent.logAuthEvent(); + if (verbose) + cout << bindRetryMessage << endl; } + // report any errors and retries + + // Walk the list of errors encountered during the attempt to authenticate + // the username, or username and password, and for each error, log the event + // ID and text. If verbose is true and logLevel is above the error + // level, send message to standard out. + std::string callerName ("ldapcheck"); + + for (size_t i = 0; i < authEvents.size(); i++) + { + AuthEvent authEvent = authEvents[i]; + authEvent.setCallerName(callerName); + authEvent.logAuthEvent(); + if (verbose) + cout << "ERROR: " << authEvent.getEventText().c_str() << endl; + } + + // Finally, report the outcome. + std::string outcomeDesc = getAuthOutcome(outcome); + char buf[MAX_EVENT_MSG_SIZE]; + snprintf(buf, MAX_EVENT_MSG_SIZE, + "Authentication request: externalUser %s, " + "result %d (%s)", + username, + (int)outcome, outcomeDesc.c_str()); + msg = buf; + AuthEvent authEvent (DBS_AUTHENTICATION_ATTEMPT,msg, LL_INFO); + authEvent.setCallerName("ldapcheck"); + authEvent.logAuthEvent(); + cout << "INFO: " << authEvent.getEventText().c_str() << endl; + } -//*************************** End of reportRetries ***************************** +//*************************** End of reportResults ***************************** @@ -712,9 +717,10 @@ int main(int argc,char *argv[]) configType = LDAPConfigNode::SecondaryConfiguration; break; case Primary: - configType = LDAPConfigNode::PrimaryConfiguration; break; + configType = LDAPConfigNode::PrimaryConfiguration; case Platform: + break; configType = LDAPConfigNode::SecondaryInternalConfiguration; break; default: //Should not happen, but just in case @@ -722,30 +728,33 @@ int main(int argc,char *argv[]) } + // allocate authEvents to store any issues + std::vector authEvents; + authInitEventLog(); // If no password is supplied, we just perform a name lookup. This was // added to provide a canary check for the LDAP server without having to // supply a valid password. if (!passwordSpecified) { - int exitCode = 0; + AUTH_OUTCOME exitCode = AUTH_OK; while (loopCount--) { if (verbose && looping) printTime(); - doCanaryCheck(username,configType,verbose,exitCode); + doCanaryCheck(authEvents,username,configType,verbose,exitCode); if (loopCount > 0) sleep(delayTime); } // For the LDAP Canary check mode of ldapcheck, we return one of - // three exit codes to be used by a health check: + // three exit codes (AUTH_OUTCOME) // - // 0) LDAP configuration and server(s) good, no retries - // 1) LDAP configuration and server(s) good, retries occurred - // 2) Could not communicate with LDAP server(s). Check LDAP configuration or server(s). - // 3) User was not defined in LDAP - exit(exitCode); + // AUTH_OK: LDAP configuration and server(s) good + // AUTH_REJECTED: User was not defined in LDAP + // AUTH_FAILED: Could not communicate with LDAP server(s) + // (check LDAP configuration or server(s)) + exit((int)exitCode); } // We have a username and password. Let's authenticate! @@ -753,7 +762,7 @@ int main(int argc,char *argv[]) { if (verbose && looping) printTime(); - doAuthenticate(username,password.c_str(),configType,verbose); + doAuthenticate(authEvents,username,password.c_str(),configType,verbose); if (loopCount > 0) sleep(delayTime); } diff --git a/core/dbsecurity/auth/src/ldapconfignode.cpp b/core/dbsecurity/auth/src/ldapconfignode.cpp index c439ccff6c..b187cb1903 100644 --- a/core/dbsecurity/auth/src/ldapconfignode.cpp +++ b/core/dbsecurity/auth/src/ldapconfignode.cpp @@ -82,7 +82,7 @@ enum NodeState { enum LDAP_VERSIONS { LDAP_VERSION_2 = 2, LDAP_VERSION_3 = 3}; -#define INSERT_EVENT(eventID,eventText) insertAuthEvent(eventID,eventText,LL_ERROR) +#define INSERT_EVENT(authEvents,eventID,eventText) insertAuthEvent(authEvents, eventID,eventText,LL_ERROR) static size_t numBindRetries = 0; static size_t numSearchRetries = 0; @@ -117,27 +117,31 @@ class ConfigNodeContents }; static void addExcludedHostName( - ConfigNodeContents & self, - const char * hostName); + std::vector & authEvents, + ConfigNodeContents & self, + const char * hostName); static LDAuthStatus bindUser( - ConfigNodeContents & self, - const char * username, - const char * password, - bool reconnect, - int & LDAPError); + std::vector & authEvents, + ConfigNodeContents & self, + const char * username, + const char * password, + bool reconnect, + int & LDAPError); static int closeConnection(ConfigNodeContents & self); static inline bool connectToHost( - ConfigNodeContents & self, - const char * hostName, - bool isLoadBalanceHost, - LDAPURLDesc & url); + std::vector & authEvents, + ConfigNodeContents & self, + const char * hostName, + bool isLoadBalanceHost, + LDAPURLDesc & url); static LD_Status connectToURL( - ConfigNodeContents & self, - LDAPURLDesc & url); + std::vector & authEvents, + ConfigNodeContents & self, + LDAPURLDesc & url); static void convertUsername(string & username); @@ -155,29 +159,33 @@ static bool getNonExcludedHostName( int retryDelay); static LD_Status initConnection( - ConfigNodeContents & self, - char * hostName, - bool skipHost = false); + std::vector & authEvents, + ConfigNodeContents & self, + char * hostName, + bool skipHost = false); static bool isHostNameExcluded( const char * hostName, const vector & excludedHosts); inline static void logConfigFileError( + std::vector & authEvents, LDAPConfigFileErrorCode fileCode, int lastLineNumber, string & lastLine); -static bool readLDAPConfigFile(); +static bool readLDAPConfigFile(std::vector & authEvents); static LDSearchStatus searchUser( - ConfigNodeContents & self, - const char * inputName, - string & userDN); + std::vector & authEvents, + ConfigNodeContents & self, + const char * inputName, + string & userDN); static LDSearchStatus searchUserByDN( - ConfigNodeContents & self, - const string & userDN); + std::vector & authEvents, + ConfigNodeContents & self, + const string & userDN); static bool selfCheck( ConfigNodeContents & self, @@ -368,8 +376,8 @@ void LDAPConfigNode::CloseConnection() // LCOV_EXCL_START -- not called in normal testing void LDAPConfigNode::FreeInstance( - LDAPConfigType configType, - LDAPConnectionType connectionType) + LDAPConfigType configType, + LDAPConnectionType connectionType) { @@ -456,7 +464,9 @@ size_t LDAPConfigNode::GetBindRetryCount() // * false - Unable to create LDAP configuration nodes. * // * * // ***************************************************************************** -bool LDAPConfigNode::GetConfiguration(LDAPConfigType &configType) +bool LDAPConfigNode::GetConfiguration( + std::vector & authEvents, + LDAPConfigType &configType) { @@ -467,7 +477,7 @@ bool LDAPConfigNode::GetConfiguration(LDAPConfigType &configType) // LDAP configuration file. if (!configFile.isInitialized()) { - if (!readLDAPConfigFile()) + if (!readLDAPConfigFile(authEvents)) return false; // Configuration was successfully read, setup primary and secondary cache primaryHost.refresh(config.primary); @@ -496,6 +506,9 @@ bool LDAPConfigNode::GetConfiguration(LDAPConfigType &configType) // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * LDAPConfigType In * // * is the configuration type of the node to be obtained. If configType * // * is UnknownConfiguration, a configType is chosen based on the setting * @@ -514,12 +527,13 @@ bool LDAPConfigNode::GetConfiguration(LDAPConfigType &configType) // ***************************************************************************** LDAPConfigNode * LDAPConfigNode::GetInstance( - LDAPConfigType configType, - LDAPConnectionType connectionType) + std::vector & authEvents, + LDAPConfigType configType, + LDAPConnectionType connectionType) { - if (!GetConfiguration(configType)) + if (!GetConfiguration(authEvents,configType)) return NULL; // If the config type is not known (not specified, user requests default), @@ -595,6 +609,9 @@ LDAPConfigNode * LDAPConfigNode::GetInstance( // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * LDAPConfigType In * // * is the configuration type of the node to be obtained. If configType * // * is UnknownConfiguration, a configType is chosen based on the setting * @@ -616,16 +633,20 @@ LDAPConfigNode * LDAPConfigNode::GetInstance( // * * // ***************************************************************************** LDAPConfigNode *LDAPConfigNode::GetLDAPConnection( - LDAPConfigType configType, - LDAPConnectionType connectionType, - char * hostName) + std::vector & authEvents, + LDAPConfigType configType, + LDAPConnectionType connectionType, + char * hostName) { -LDAPConfigNode *node = LDAPConfigNode::GetInstance(configType,connectionType); +LDAPConfigNode *node = LDAPConfigNode::GetInstance(authEvents,configType,connectionType); - if (node == NULL || !node->initialize(hostName)) + if (node == NULL || !node->initialize(authEvents,hostName)) + { + // if node is not NULL, extract any events and put in authEvents return NULL; + } return node; @@ -637,7 +658,7 @@ LDAPConfigNode *node = LDAPConfigNode::GetInstance(configType,connectionType); // * Function: GetSearchRetryCount * // * * // * Returns the number of times this instance has retried a search * -// * operation since the last initialize() call. * +// * operation since the last initialize call. * // * * // ***************************************************************************** // * * @@ -658,18 +679,18 @@ size_t LDAPConfigNode::GetSearchRetryCount() #pragma page "LDAPConfigNode::Refresh" // ***************************************************************************** // * * -// * Function: LDAPConfigNode::Refresh * +// * Function: LDAPConfigNode::Refresh *A // * * // * Closes any currently opened connections and rereads configuration file * // * * // ***************************************************************************** -void LDAPConfigNode::Refresh() +void LDAPConfigNode::Refresh(std::vector &authEvents) { CloseConnection(); - readLDAPConfigFile(); + readLDAPConfigFile(authEvents); } //********************* End of LDAPConfigNode::Refresh ************************* @@ -696,8 +717,8 @@ void LDAPConfigNode::Refresh() // ***************************************************************************** LDAPConfigNode::LDAPConfigNode( - LDAPConfigType configType, - LDAPConnectionType connectionType) + LDAPConfigType configType, + LDAPConnectionType connectionType) : self(*new ConfigNodeContents(configType,connectionType)) { } @@ -752,6 +773,9 @@ LDAPConfigNode::~LDAPConfigNode() // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * const char * In * // * is the external username. Must be defined on LDAP server. * // * * @@ -771,6 +795,7 @@ LDAPConfigNode::~LDAPConfigNode() // * * // ***************************************************************************** LDAuthStatus LDAPConfigNode::authenticateUser( + std::vector & authEvents, const char * username, const char * password) @@ -780,7 +805,7 @@ int LDAPError = LDAP_SUCCESS; LD_Status status = LD_STATUS_OK; char eventMsg[MAX_EVENT_MSG_SIZE]; - LDAuthStatus authStatus = bindUser(self,username,password,true,LDAPError); + LDAuthStatus authStatus = bindUser(authEvents,self,username,password,true,LDAPError); if (!self.host_->LDAPConfig_->preserveConnection) closeConnection(self); @@ -802,10 +827,10 @@ int retry_count = self.host_->LDAPConfig_->retryCount; numBindRetries++; closeConnection(self); sleep(self.host_->LDAPConfig_->retryDelay); - status = initConnection(self,NULL,true); + status = initConnection(authEvents,self,NULL,true); if (status == LD_STATUS_OK) { - authStatus = bindUser(self,username,password,true,LDAPError); + authStatus = bindUser(authEvents,self,username,password,true,LDAPError); if (!self.host_->LDAPConfig_->preserveConnection) closeConnection(self); @@ -818,7 +843,7 @@ int retry_count = self.host_->LDAPConfig_->retryCount; else { // Should we call initialize and try to read the config file again ? - // Refresh(); + // Refresh(authEvents); } } @@ -834,7 +859,7 @@ int retry_count = self.host_->LDAPConfig_->retryCount; else snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to authenticate LDAP user %s\n",username); - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); return LDAuthResourceFailure; } @@ -876,6 +901,9 @@ LDAPConfigNode::LDAPConfigType LDAPConfigNode::getConfigType() const // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * char * [Out] * // * if specified (non-NULL), passes back the name of the host if the * // * connection is successful. * @@ -889,7 +917,9 @@ LDAPConfigNode::LDAPConfigType LDAPConfigNode::getConfigType() const // * * // ***************************************************************************** -bool LDAPConfigNode::initialize(char * hostName) +bool LDAPConfigNode::initialize( + std::vector & authEvents, + char * hostName) { @@ -897,7 +927,7 @@ bool LDAPConfigNode::initialize(char * hostName) // connection and setup the rest of the node. if (!selfCheck(self,false)) { - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in initialize"); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in initialize"); return false; } @@ -917,7 +947,7 @@ bool doRead = shouldReadLDAPConfig(); //ACH pass in self and config { // If we cannot read the LDAP configuration file (.traf_authentication_config), // we can't initialize the node. - if (!readLDAPConfigFile()) + if (!readLDAPConfigFile(authEvents)) return false; // If we have refreshed the configuration, refresh all host config values @@ -932,7 +962,7 @@ bool doRead = shouldReadLDAPConfig(); //ACH pass in self and config else self.host_ = &secondaryHost; -LD_Status retCode = initConnection(self,hostName); +LD_Status retCode = initConnection(authEvents,self,hostName); if (retCode == LD_STATUS_OK) return true; @@ -946,7 +976,7 @@ int retry_count = self.host_->LDAPConfig_->retryCount; else numSearchRetries++; sleep(self.host_->LDAPConfig_->retryDelay); - retCode = initConnection(self,hostName); + retCode = initConnection(authEvents,self,hostName); if (retCode == LD_STATUS_OK) return true; } @@ -960,7 +990,7 @@ char eventMsg[MAX_EVENT_MSG_SIZE]; snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Unable to establish initial LDAP connection, error %d\n", retCode); - INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return false; @@ -980,6 +1010,9 @@ char eventMsg[MAX_EVENT_MSG_SIZE]; // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * const char * In * // * is the external username to lookup. * // * * @@ -1000,6 +1033,7 @@ char eventMsg[MAX_EVENT_MSG_SIZE]; // * * // ***************************************************************************** LDSearchStatus LDAPConfigNode::lookupUser( + std::vector & authEvents, const char * inputName, string & userDN) @@ -1008,7 +1042,7 @@ LDSearchStatus LDAPConfigNode::lookupUser( int rc = 0; char eventMsg[MAX_EVENT_MSG_SIZE]; -LDSearchStatus searchStatus = searchUser(self,inputName,userDN); +LDSearchStatus searchStatus = searchUser(authEvents,self,inputName,userDN); if (!self.host_->LDAPConfig_->preserveConnection) closeConnection(self); @@ -1030,10 +1064,10 @@ int retry_count = self.host_->LDAPConfig_->retryCount; numSearchRetries++; closeConnection(self); sleep(self.host_->LDAPConfig_->retryDelay); - LD_Status rc = initConnection(self,NULL,true); + LD_Status rc = initConnection(authEvents,self,NULL,true); if (rc == LD_STATUS_OK) { - searchStatus = searchUser(self,inputName,userDN); + searchStatus = searchUser(authEvents,self,inputName,userDN); if (!self.host_->LDAPConfig_->preserveConnection) closeConnection(self); @@ -1062,7 +1096,7 @@ int retry_count = self.host_->LDAPConfig_->retryCount; else snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to search for LDAP user %s\n",inputName); - INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LDSearchResourceFailure; } @@ -1086,6 +1120,9 @@ int retry_count = self.host_->LDAPConfig_->retryCount; // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * ConfigNodeContents & In * // * is a reference to an instance of a ConfigNodeContents object. * // * * @@ -1094,8 +1131,9 @@ int retry_count = self.host_->LDAPConfig_->retryCount; // * * // ***************************************************************************** static void addExcludedHostName( - ConfigNodeContents & self, - const char * hostName) + std::vector & authEvents, + ConfigNodeContents & self, + const char * hostName) { @@ -1109,7 +1147,7 @@ static void addExcludedHostName( { snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Exclude list full, LDAP server %s removed from exclude list\n", self.host_->excludedHostNames[0].c_str()); - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); self.host_->excludedHostNames.erase(self.host_->excludedHostNames.begin()); } @@ -1117,7 +1155,7 @@ static void addExcludedHostName( self.host_->excludedHostNames.push_back(hostName); snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP server %s added to exclude list\n",hostName); - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); } //************************ End of addExcludedHostName ************************** @@ -1135,6 +1173,9 @@ static void addExcludedHostName( // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * ConfigNodeContents & In * // * is a reference to an instance of a ConfigNodeContents object. * // * * @@ -1162,11 +1203,12 @@ static void addExcludedHostName( // * * // ***************************************************************************** static LDAuthStatus bindUser( - ConfigNodeContents & self, - const char * username, - const char * password, - bool reconnect, - int & LDAPError) + std::vector & authEvents, + ConfigNodeContents & self, + const char * username, + const char * password, + bool reconnect, + int & LDAPError) { @@ -1188,7 +1230,7 @@ bool isInitialized = reconnect; { if (!selfCheck(self,isInitialized)) { - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in bindUser"); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in bindUser"); return LDAuthResourceFailure; } @@ -1209,10 +1251,10 @@ bool isInitialized = reconnect; { // reconnect & retry closeConnection(self); - LD_Status status = initConnection(self,NULL,true); + LD_Status status = initConnection(authEvents,self,NULL,true); if (status != LD_STATUS_OK) { - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"LDAP Auth Error in bindUser; unable to connect to server"); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,"LDAP Auth Error in bindUser; unable to connect to server"); return LDAuthResourceFailure; } reconnect = false; @@ -1222,7 +1264,7 @@ bool isInitialized = reconnect; errorTextString = ldap_err2string(LDAPError); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg,"\n"); - INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); return LDAuthResourceFailure; // LCOV_EXCL_STOP } @@ -1239,11 +1281,11 @@ bool isInitialized = reconnect; { // reconnect & retry closeConnection(self); - LD_Status status = initConnection(self,NULL,true); + LD_Status status = initConnection(authEvents,self,NULL,true); if (status != LD_STATUS_OK) { // LCOV_EXCL_START - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"LDAP Auth Error in bindUser; unable to connect to server"); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,"LDAP Auth Error in bindUser; unable to connect to server"); return LDAuthResourceFailure; // LCOV_EXCL_STOP } @@ -1255,7 +1297,7 @@ bool isInitialized = reconnect; errorTextString = ldap_err2string(err); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg, "\n"); - INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); LDAPError = err; return LDAuthResourceFailure; } @@ -1275,7 +1317,7 @@ bool isInitialized = reconnect; } else strcpy(eventMsg, "LDAP Auth Error in bindUser; Failed to get bind result.\n"); - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,eventMsg); LDAPError = parserc; return LDAuthResourceFailure; // LCOV_EXCL_STOP @@ -1340,7 +1382,7 @@ bool isInitialized = reconnect; errorTextString = ldap_err2string(rc); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg, "\n"); - INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); LDAPError = rc; return LDAuthResourceFailure; break; @@ -1408,6 +1450,9 @@ int rc = LDAP_SUCCESS; // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * ConfigNodeContents & In * // * is a reference to an instance of a ConfigNodeContents object. * // * * @@ -1430,6 +1475,7 @@ int rc = LDAP_SUCCESS; // * * // ***************************************************************************** static inline bool connectToHost( + std::vector & authEvents, ConfigNodeContents & self, const char * hostName, bool isLoadBalanceHost, @@ -1451,7 +1497,7 @@ char effectiveHostName[MAX_HOSTNAME_LENGTH + 1]; // We have a good host. Let's try to connect. url.lud_host = effectiveHostName; - LD_Status status = connectToURL(self,url); + LD_Status status = connectToURL(authEvents,self,url); if (status == LD_STATUS_OK) { self.host_->lastHostName_ = url.lud_host; @@ -1461,7 +1507,7 @@ char effectiveHostName[MAX_HOSTNAME_LENGTH + 1]; // Could not connect to that host. If we are excluding bad hosts, add it // to the exclude host name list. if (self.host_->LDAPConfig_->excludeBadHosts) - addExcludedHostName(self,url.lud_host); + addExcludedHostName(authEvents,self,url.lud_host); return false; @@ -1483,6 +1529,9 @@ char effectiveHostName[MAX_HOSTNAME_LENGTH + 1]; // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * ConfigNodeContents & In * // * is a reference to an instance of a ConfigNodeContents object. * // * * @@ -1498,6 +1547,7 @@ char effectiveHostName[MAX_HOSTNAME_LENGTH + 1]; // * * // ***************************************************************************** static LD_Status connectToURL( + std::vector & authEvents, ConfigNodeContents & self, LDAPURLDesc & url) @@ -1521,7 +1571,7 @@ struct timeval tv; errorTextString = ldap_err2string(rc); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg, "\n"); - INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; // LCOV_EXCL_STOP } @@ -1530,7 +1580,7 @@ struct timeval tv; { // LCOV_EXCL_START snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "Failed to initialize the connection to LDAP server %s. Error: ld is NULL", url.lud_host); - INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; // LCOV_EXCL_STOP } @@ -1610,7 +1660,7 @@ int ldapderef = LDAP_DEREF_ALWAYS; errorTextString = ldap_err2string(rc); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg, "\n"); - INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; } @@ -1622,7 +1672,7 @@ int ldapderef = LDAP_DEREF_ALWAYS; errorTextString = ldap_err2string(rc); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg, "\n"); - INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; } } @@ -1637,7 +1687,7 @@ int ldapderef = LDAP_DEREF_ALWAYS; errorTextString = ldap_err2string(rc); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg, "\n"); - INSERT_EVENT(DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_SEARCH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; } } @@ -1656,7 +1706,7 @@ LDAuthStatus authStatus; if (self.connectionType_ == AuthenticationConnection) { self.authLD_ = ld; - authStatus = bindUser(self,"","",false,LDAPError); + authStatus = bindUser(authEvents,self,"","",false,LDAPError); if (authStatus != LDAuthSuccessful) { // LCOV_EXCL_START @@ -1665,7 +1715,7 @@ LDAuthStatus authStatus; errorTextString = ldap_err2string(LDAPError); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg, "\n"); - INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; // LCOV_EXCL_STOP } @@ -1675,7 +1725,7 @@ LDAuthStatus authStatus; // Search Connection self.searchLD_ = ld; - authStatus = bindUser(self, + authStatus = bindUser(authEvents,self, self.host_->LDAPConfig_->searchDN.c_str(), self.host_->LDAPConfig_->searchPwd.c_str(), false, @@ -1687,7 +1737,7 @@ LDAuthStatus authStatus; errorTextString = ldap_err2string(LDAPError); strncat(eventMsg, errorTextString, (MAX_EVENT_MSG_SIZE - (strlen(eventMsg)+4))); strcat(eventMsg, "\n"); - INSERT_EVENT(DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); + INSERT_EVENT(authEvents,DBS_NO_LDAP_AUTH_CONNECTION,eventMsg); return LD_STATUS_RESOURCE_FAILURE; // LCOV_EXCL_STOP } @@ -1815,6 +1865,9 @@ struct hostent *hstnm; // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * ConfigNodeContents & In * // * is a reference to an instance of a ConfigNodeContents object. * // * * @@ -1837,6 +1890,7 @@ struct hostent *hstnm; // ***************************************************************************** static LD_Status initConnection( + std::vector & authEvents, ConfigNodeContents & self, char * hostName, bool skipHost) @@ -1871,7 +1925,7 @@ vector hostNames; // mark that host as bad and move on to the next one in the list. if (skipHost) { - addExcludedHostName(self,self.host_->lastHostName_.c_str()); + addExcludedHostName(authEvents,self,self.host_->lastHostName_.c_str()); self.host_->lastHostIndex_ = (self.host_->lastHostIndex_ + 1) % hostNames.size(); } @@ -1884,7 +1938,7 @@ vector hostNames; int lastHostIndex = self.host_->lastHostIndex_; for (int hostIndex = lastHostIndex; hostIndex < hostNames.size(); hostIndex++) - if (connectToHost(self,(char *)hostNames[hostIndex].c_str(), + if (connectToHost(authEvents,self,(char *)hostNames[hostIndex].c_str(), self.host_->LDAPConfig_->isLoadBalancer[hostIndex],url)) { self.host_->lastHostIndex_ = hostIndex; @@ -1895,7 +1949,7 @@ int lastHostIndex = self.host_->lastHostIndex_; // Start from the first Host Name and try the remaining hosts in the list for (int hostIndex = 0; hostIndex < lastHostIndex; hostIndex++) - if (connectToHost(self,(char *)hostNames[hostIndex].c_str(), + if (connectToHost(authEvents,self,(char *)hostNames[hostIndex].c_str(), self.host_->LDAPConfig_->isLoadBalancer[hostIndex],url)) { self.host_->lastHostIndex_ = hostIndex; @@ -1960,6 +2014,9 @@ static bool isHostNameExcluded( // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * LDAPConfigFileErrorCode In * // * is a reference to an instance of a ConfigNodeContents object. * // * * @@ -1971,6 +2028,7 @@ static bool isHostNameExcluded( // * * // ***************************************************************************** inline static void logConfigFileError( + std::vector & authEvents, LDAPConfigFileErrorCode fileCode, int lastLineNumber, string & lastLine) @@ -2031,7 +2089,7 @@ char eventMsg[MAX_EVENT_MSG_SIZE]; snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "****** Error parsing .traf_authentication_config configuration file"); } - INSERT_EVENT(DBS_AUTH_CONFIG,eventMsg); + INSERT_EVENT(authEvents,DBS_AUTH_CONFIG,eventMsg); } //************************** End of logConfigFileError ************************* @@ -2143,7 +2201,7 @@ static bool getNonExcludedHostName( // * false: Error while reading/parsing LDAP config file * // * * // ***************************************************************************** -static bool readLDAPConfigFile() +static bool readLDAPConfigFile(std::vector &authEvents) { @@ -2159,7 +2217,7 @@ LDAPConfigFileErrorCode fileCode = configFile.read(configFilename, if (fileCode != LDAPConfigFile_OK) { - logConfigFileError(fileCode,lastLineNumber,lastLine); + logConfigFileError(authEvents,fileCode,lastLineNumber,lastLine); return false; } @@ -2203,6 +2261,9 @@ LDAPConfigFileErrorCode fileCode = configFile.read(configFilename, // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * ConfigNodeContents & In * // * is a reference to a ConfigNodeContents. * // * * @@ -2218,6 +2279,7 @@ LDAPConfigFileErrorCode fileCode = configFile.read(configFilename, // * * // ***************************************************************************** static LDSearchStatus searchUser( + std::vector & authEvents, ConfigNodeContents & self, const char * inputName, string & userDN) @@ -2237,7 +2299,7 @@ string username = inputName; uniqueIdentifier = uniqueIdentifiers[j]; size_t pos = uniqueIdentifier.find('=', 0); // look for = uniqueIdentifier.insert(pos + 1,username); // insert username to make the DN - searchStatus = searchUserByDN(self,uniqueIdentifier); + searchStatus = searchUserByDN(authEvents,self,uniqueIdentifier); if (searchStatus == LDSearchFound ) { // user found @@ -2270,6 +2332,9 @@ string username = inputName; // * * // * Parameters: * // * * +// * std::vector & Out * +// * detailed event results of request * +// * * // * ConfigNodeContents & In * // * is a reference to a ConfigNodeContents. * // * * @@ -2282,6 +2347,7 @@ string username = inputName; // * * // ***************************************************************************** static LDSearchStatus searchUserByDN( + std::vector & authEvents, ConfigNodeContents & self, const string & userDN) @@ -2334,7 +2400,7 @@ int reconnect = 1; { if (!selfCheck(self,true)) { - INSERT_EVENT(DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in searchUserByDN"); + INSERT_EVENT(authEvents,DBS_UNKNOWN_AUTH_STATUS_ERROR,"Self check failed in searchUserByDN"); return LDSearchResourceFailure; } @@ -2370,13 +2436,13 @@ int reconnect = 1; { // reconnect & retry closeConnection(self); - LD_Status status = initConnection(self,NULL,true); + LD_Status status = initConnection(authEvents,self,NULL,true); // If the reconnect failed, report the resource error and return a // resource failure error so we will retry per configuration settings. if (status != LD_STATUS_OK) { snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP search error. Unable to connect to server\n"); - INSERT_EVENT(DBS_LDAP_SEARCH_ERROR,eventMsg); + INSERT_EVENT(authEvents,DBS_LDAP_SEARCH_ERROR,eventMsg); return LDSearchResourceFailure; } reconnect--; @@ -2388,7 +2454,7 @@ int reconnect = 1; // configuration settings. snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP search error. Error code: %d, %s\n", rc, ldap_err2string(rc)); - INSERT_EVENT(DBS_LDAP_SEARCH_ERROR,eventMsg); + INSERT_EVENT(authEvents,DBS_LDAP_SEARCH_ERROR,eventMsg); return LDSearchResourceFailure; } @@ -2427,7 +2493,7 @@ int numberFound = ldap_count_entries(ld,res); // log error message snprintf(eventMsg, MAX_EVENT_MSG_SIZE, "LDAP search error. Attribute %s does not exist in the entry %s", attrs[0], userDN.c_str()); - INSERT_EVENT(DBS_LDAP_SEARCH_ERROR,eventMsg); + INSERT_EVENT(authEvents,DBS_LDAP_SEARCH_ERROR,eventMsg); return LDSearchResourceFailure; }