[TRAFODION-1794]: Log authentication Information Made changes suggested by previous delivery
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/3e05c90d Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/3e05c90d Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/3e05c90d Branch: refs/heads/master Commit: 3e05c90de214174e5735aadcb0ea1232355ababf Parents: 77c6949 Author: Roberta Marton <rmarton@edev07.esgyn.local> Authored: Tue Sep 20 00:04:40 2016 +0000 Committer: Roberta Marton <rmarton@edev07.esgyn.local> Committed: Tue Sep 20 00:04:40 2016 +0000 ---------------------------------------------------------------------- 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(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/conn/odbc/src/odbc/nsksrvrcore/Makefile ---------------------------------------------------------------------- diff --git a/core/conn/odbc/src/odbc/nsksrvrcore/Makefile b/core/conn/odbc/src/odbc/nsksrvrcore/Makefile index 5490cbe..53cb1fb 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 http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/dbsecurity/auth/Makefile ---------------------------------------------------------------------- diff --git a/core/dbsecurity/auth/Makefile b/core/dbsecurity/auth/Makefile index acb26f6..9bd67e6 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) http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/dbsecurity/auth/inc/auth.h ---------------------------------------------------------------------- diff --git a/core/dbsecurity/auth/inc/auth.h b/core/dbsecurity/auth/inc/auth.h index 68d9b42..2b51371 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 http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/dbsecurity/auth/inc/authEvents.h ---------------------------------------------------------------------- diff --git a/core/dbsecurity/auth/inc/authEvents.h b/core/dbsecurity/auth/inc/authEvents.h index 8c4cefa..cd53ea5 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<AuthEvent> authEvents; - void authInitEventLog(); - void insertAuthEvent( + std::vector<AuthEvent> & authEvents, DB_SECURITY_EVENTID eventID, const char * eventText, logLevel severity); http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/dbsecurity/auth/inc/dbUserAuth.h ---------------------------------------------------------------------- diff --git a/core/dbsecurity/auth/inc/dbUserAuth.h b/core/dbsecurity/auth/inc/dbUserAuth.h index ba48216..db0142b 100644 --- a/core/dbsecurity/auth/inc/dbUserAuth.h +++ b/core/dbsecurity/auth/inc/dbUserAuth.h @@ -24,6 +24,7 @@ #include <stddef.h> #include <stdint.h> #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 http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/dbsecurity/auth/inc/ldapconfignode.h ---------------------------------------------------------------------- diff --git a/core/dbsecurity/auth/inc/ldapconfignode.h b/core/dbsecurity/auth/inc/ldapconfignode.h index 0d724af..3a7eda9 100644 --- a/core/dbsecurity/auth/inc/ldapconfignode.h +++ b/core/dbsecurity/auth/inc/ldapconfignode.h @@ -23,6 +23,7 @@ // @@@ END COPYRIGHT @@@ //****************************************************************************** #include <string> +#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<AuthEvent> & authEvents, + LDAPConfigType configType, + LDAPConnectionType connectionType, + char * hostName = NULL); + static LDAPConfigNode * GetInstance( - LDAPConfigType configType, - LDAPConnectionType connectionType); + std::vector<AuthEvent> & authEvents, + LDAPConfigType configType, + LDAPConnectionType connectionType); + static size_t GetSearchRetryCount(); - static void Refresh(); + + static void Refresh(std::vector<AuthEvent> & authEvents); + static const char * TestGetConfigFilename(); LDAuthStatus authenticateUser( - const char *username, - const char *password); + std::vector<AuthEvent> & authEvents, + const char * username, + const char * password); LDAPConfigType getConfigType() const; LDSearchStatus lookupUser( - const char *inputName, - string &userDN); + std::vector<AuthEvent> & 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<AuthEvent> & authEvents, + LDAPConfigType & configType); + static void GetDefaultConfiguration(); - bool initialize(char * hostName); - + bool initialize( + std::vector<AuthEvent> & authEvents, + char * hostName); }; #endif http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/dbsecurity/auth/src/authEvents.cpp ---------------------------------------------------------------------- diff --git a/core/dbsecurity/auth/src/authEvents.cpp b/core/dbsecurity/auth/src/authEvents.cpp index 19cd90c..24cbcd1 100644 --- a/core/dbsecurity/auth/src/authEvents.cpp +++ b/core/dbsecurity/auth/src/authEvents.cpp @@ -25,11 +25,11 @@ #include <unistd.h> #include <stdio.h> #include <iostream> -#include "seabed/ms.h" -#include "seabed/fserr.h" + +class AuthEvent; static std::string AUTH_COMPONENT = "DBSECURITY"; -std::vector<AuthEvent> authEvents; + // **************************************************************************** // function: insertAuthEvent @@ -42,12 +42,13 @@ std::vector<AuthEvent> authEvents; // severity - severity of the event // **************************************************************************** void insertAuthEvent( + std::vector<AuthEvent> & authEvents, DB_SECURITY_EVENTID eventID, const char * eventText, logLevel severity) { AuthEvent authEvent(eventID, - AuthEvent::formatEventText(eventText), + eventText, severity); authEvents.push_back(authEvent); } @@ -84,6 +85,47 @@ void authInitEventLog() } // **************************************************************************** +// 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 // // This method formats event text into a message that can be added to the @@ -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 http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/dbsecurity/auth/src/dbUserAuth.cpp ---------------------------------------------------------------------- diff --git a/core/dbsecurity/auth/src/dbUserAuth.cpp b/core/dbsecurity/auth/src/dbUserAuth.cpp index 3ab2dbe..80cf6c0 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<AuthEvent> & authEvents); static void logAuthenticationOutcome( const string & external_user_name, @@ -182,13 +182,15 @@ public: class DBUserAuthContents { public: - BlackBox bb; - int nodeID; + BlackBox bb; + int nodeID; + std::vector<AuthEvent> authEvents; int bypassAuthentication( Token & token, AUTHENTICATION_INFO & authenticationInfo); + std::vector<AuthEvent> &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<AuthEvent> 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<AuthEvent> &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(); } http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/3e05c90d/core/dbsecurity/auth/src/ldapcheck.cpp ---------------------------------------------------------------------- diff --git a/core/dbsecurity/auth/src/ldapcheck.cpp b/core/dbsecurity/auth/src/ldapcheck.cpp index 3b965be..62f6d92 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 <stdio.h> #include <string.h> @@ -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<AuthEvent> & authEvents, const char * username, const char * password, LDAPConfigNode::LDAPConfigType configType, @@ -66,28 +63,34 @@ LDAPAuthResult authenticateLDAPUser( char * authHostName); void doAuthenticate( + std::vector<AuthEvent> & authEvents, const char * username, const char * password, LDAPConfigNode::LDAPConfigType configType, bool verbose); void doCanaryCheck( + std::vector<AuthEvent> & authEvents, const char * username, LDAPConfigNode::LDAPConfigType configType, bool verbose, - int & exitCode); + AUTH_OUTCOME exitCode); LDSearchStatus lookupLDAPUser( + std::vector<AuthEvent> & authEvents, const char * username, LDAPConfigNode::LDAPConfigType configType, char * searchHostName); void printTime(); -void reportAuthenticationErrors(bool displayErrors); +void reportResults( + Operation operation, + const std::vector<AuthEvent> & 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: * // * * +// * <authEvents> std::vector<AuthEvent> & Out * +// * detailed event results of request * +// * * // * <username> 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<AuthEvent> & 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: * // * * +// * <authEvents> std::vector<AuthEvent> & Out * +// * detailed event results of request * +// * * // * <username> 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<AuthEvent> & 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: * // * * +// * <authEvents> std::vector<AuthEvent> & Out * +// * detailed event results of request * +// * * // * <username> 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<AuthEvent> & 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: * // * * +// * <authEvents> std::vector<AuthEvent> & Out * +// * detailed event results of request * +// * * // * <username> const char * In * // * is the external username to be checked on the directory server. * // * * @@ -355,6 +340,7 @@ void doCanaryCheck( // * * // ***************************************************************************** LDSearchStatus lookupLDAPUser( + std::vector<AuthEvent> & 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 ***************************** @@ -423,82 +409,101 @@ 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<AuthEvent> & 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<AuthEvent> 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); }