From 5da7b0847bac2a5abec95b9ac1701b74baae8964 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 16 Aug 2009 12:56:14 +0200 Subject: UserConfigBackendKrb5: Neu verbinden, wenn die Verbindung zur Datenbank abgebrochen ist --- .../UserConfigBackendKrb5.cpp | 87 ++++++++++++++++++---- .../UserConfigBackendKrb5/UserConfigBackendKrb5.h | 3 +- 2 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp index 9a43691..beedbae 100644 --- a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp +++ b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp @@ -27,17 +27,20 @@ namespace Mad { namespace Modules { namespace UserConfigBackendKrb5 { -bool UserConfigBackendKrb5::connect() { +void UserConfigBackendKrb5::connect() { if(principal.empty()) { application->log(Core::LoggerBase::USER, Core::LoggerBase::ERROR, "UserConfigBackendKrb5: no principal given"); - return false; + return; } if(realm.empty()) { application->log(Core::LoggerBase::USER, Core::LoggerBase::ERROR, "UserConfigBackendKrb5: no realm given and no default realm available"); - return false; + return; } + if(!context) + return; + if(handle) { kadm5_destroy(handle); handle = 0; @@ -61,8 +64,8 @@ bool UserConfigBackendKrb5::connect() { const_cast(KADM5_ADMIN_SERVICE), ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, 0, &handle); if(err) { - application->logf(Core::LoggerBase::USER, Core::LoggerBase::ERROR, "kadm5_init_with_password: %s", std::strerror(err)); - return false; + application->logf(Core::LoggerBase::USER, Core::LoggerBase::ERROR, "kadm5_init_with_password: %s", krb5_get_error_message(context, err)); + return; } } else { @@ -74,13 +77,13 @@ bool UserConfigBackendKrb5::connect() { const_cast(KADM5_ADMIN_SERVICE), ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, 0, &handle); if(err) { - application->logf(Core::LoggerBase::USER, Core::LoggerBase::ERROR, "kadm5_init_with_skey: %s", std::strerror(err)); - return false; + application->logf(Core::LoggerBase::USER, Core::LoggerBase::ERROR, "kadm5_init_with_skey: %s", krb5_get_error_message(context, err)); + return; } } application->log(Core::LoggerBase::USER, Core::LoggerBase::VERBOSE, "Connected to kerberos admin server."); - return true; + return; } bool UserConfigBackendKrb5::handleConfigEntry(const Core::ConfigEntry &entry, bool /*handled*/) { @@ -126,6 +129,9 @@ void UserConfigBackendKrb5::checkUserInfo(const Common::UserInfo &userInfo) thro } void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core::Exception) { + if(!context || !handle) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + application->getThreadManager()->detach(); std::string princStr = userInfo.getUsername() + "@" + realm; @@ -142,20 +148,43 @@ void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core for(int i = 0; i < 128; ++i) dummybuf[i] = (i+1)%128; - err = kadm5_create_principal(handle, &princ, KADM5_PRINCIPAL|KADM5_ATTRIBUTES, dummybuf); + int retryCount = 3; + + do { + err = kadm5_create_principal(handle, &princ, KADM5_PRINCIPAL|KADM5_ATTRIBUTES, dummybuf); + if(err == KADM5_RPC_ERROR && retryCount > 0) { + application->log(Core::LoggerBase::USER, Core::LoggerBase::VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); + connect(); + --retryCount; + } + } while(err == KADM5_RPC_ERROR && retryCount >= 0); if(err) { krb5_free_principal(context, princ.principal); throw Core::Exception("kadm5_create_principal", Core::Exception::INTERNAL_ERRNO, err); } - err = kadm5_randkey_principal(handle, princ.principal, 0, 0); + do { + err = kadm5_randkey_principal(handle, princ.principal, 0, 0); + if(err == KADM5_RPC_ERROR && retryCount > 0) { + application->log(Core::LoggerBase::USER, Core::LoggerBase::VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); + connect(); + --retryCount; + } + } while(err == KADM5_RPC_ERROR && retryCount >= 0); if(err) { krb5_free_principal(context, princ.principal); throw Core::Exception("kadm5_randkey_principal", Core::Exception::INTERNAL_ERRNO, err); } princ.attributes = 0; - err = kadm5_modify_principal(handle, &princ, KADM5_ATTRIBUTES); + do { + err = kadm5_modify_principal(handle, &princ, KADM5_ATTRIBUTES); + if(err == KADM5_RPC_ERROR && retryCount > 0) { + application->log(Core::LoggerBase::USER, Core::LoggerBase::VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); + connect(); + --retryCount; + } + } while(err == KADM5_RPC_ERROR && retryCount >= 0); krb5_free_principal(context, princ.principal); @@ -164,6 +193,9 @@ void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core } void UserConfigBackendKrb5::updateUser(const Common::UserInfo &oldUserInfo, const Common::UserInfo &userInfo) throw(Core::Exception) { + if(!context || !handle) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + if(oldUserInfo.getUsername() == userInfo.getUsername()) return; @@ -172,6 +204,9 @@ void UserConfigBackendKrb5::updateUser(const Common::UserInfo &oldUserInfo, cons } void UserConfigBackendKrb5::deleteUser(const Common::UserInfo &userInfo) throw(Core::Exception) { + if(!context || !handle) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + application->getThreadManager()->detach(); std::string princStr = userInfo.getUsername() + "@" + realm; @@ -181,15 +216,28 @@ void UserConfigBackendKrb5::deleteUser(const Common::UserInfo &userInfo) throw(C if(err) throw Core::Exception("krb5_parse_name", Core::Exception::INTERNAL_ERRNO, err); - /*err = */kadm5_delete_principal(handle, princ); + + int retryCount = 3; + + do { + err = kadm5_delete_principal(handle, princ); + if(err == KADM5_RPC_ERROR && retryCount > 0) { + application->log(Core::LoggerBase::USER, Core::LoggerBase::VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); + connect(); + --retryCount; + } + } while(err == KADM5_RPC_ERROR && retryCount >= 0); krb5_free_principal(context, princ); - //if(err) - // throw Core::Exception("kadm5_delete_principal", Core::Exception::INTERNAL_ERRNO, err); + if(err) + application->logf(Core::LoggerBase::USER, Core::LoggerBase::WARNING, "kadm5_delete_principal: %s", krb5_get_error_message(context, err)); } void UserConfigBackendKrb5::setPassword(const Common::UserInfo &userInfo, const std::string &password) throw(Core::Exception) { + if(!context || !handle) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + application->getThreadManager()->detach(); std::string princStr = userInfo.getUsername() + "@" + realm; @@ -199,7 +247,16 @@ void UserConfigBackendKrb5::setPassword(const Common::UserInfo &userInfo, const if(err) throw Core::Exception("krb5_parse_name", Core::Exception::INTERNAL_ERRNO, err); - err = kadm5_chpass_principal(handle, princ, const_cast(password.c_str())); + int retryCount = 3; + + do { + err = kadm5_chpass_principal(handle, princ, const_cast(password.c_str())); + if(err == KADM5_RPC_ERROR && retryCount > 0) { + application->log(Core::LoggerBase::USER, Core::LoggerBase::VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); + connect(); + --retryCount; + } + } while(err == KADM5_RPC_ERROR && retryCount >= 0); krb5_free_principal(context, princ); diff --git a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h index 6571220..11c7187 100644 --- a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h +++ b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h @@ -43,7 +43,7 @@ class UserConfigBackendKrb5 : public Common::UserConfigBackend, private Core::Co krb5_context context; void *handle; - bool connect(); + void connect(); protected: virtual bool handleConfigEntry(const Core::ConfigEntry &entry, bool handled); @@ -64,6 +64,7 @@ class UserConfigBackendKrb5 : public Common::UserConfigBackend, private Core::Co UserConfigBackendKrb5(Common::Application *application0) : application(application0), handle(0) { krb5_error_code err = krb5_init_context(&context); if(err) { + application->logf("Unable to initialize kerberos context: %s", std::strerror(err)); context = 0; return; } -- cgit v1.2.3