diff options
-rw-r--r-- | src/Client/CommandParser.cpp | 1 | ||||
-rw-r--r-- | src/Client/UserCommands.cpp | 64 | ||||
-rw-r--r-- | src/Client/UserCommands.h | 2 | ||||
-rw-r--r-- | src/Common/Backends/NetworkUserBackend.cpp | 27 | ||||
-rw-r--r-- | src/Common/Backends/NetworkUserBackend.h | 17 | ||||
-rw-r--r-- | src/Common/UserCache.h | 10 | ||||
-rw-r--r-- | src/Common/UserConfigBackend.h | 22 | ||||
-rw-r--r-- | src/Common/UserDBBackend.h | 10 | ||||
-rw-r--r-- | src/Common/UserManager.cpp | 43 | ||||
-rw-r--r-- | src/Common/UserManager.h | 4 | ||||
-rw-r--r-- | src/Server/RequestHandlers/UserRequestHandlerGroup.cpp | 9 | ||||
-rw-r--r-- | src/Server/RequestHandlers/UserRequestHandlerGroup.h | 2 | ||||
-rw-r--r-- | src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp | 23 | ||||
-rw-r--r-- | src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h | 2 |
14 files changed, 203 insertions, 33 deletions
diff --git a/src/Client/CommandParser.cpp b/src/Client/CommandParser.cpp index b06f4b4..56ecbba 100644 --- a/src/Client/CommandParser.cpp +++ b/src/Client/CommandParser.cpp @@ -55,6 +55,7 @@ const CommandParser::Command CommandParser::commands[] = { {{"delete_group", 0}, "delete_group did", "Delete group", "Delete a user group from the account database.", &UserCommands::deleteGroupCommand}, {{"add_user_to_group", 0}, "add_user_to_group uid gid", "Add a user to a group", "Add a user to a group.", &UserCommands::addUserToGroupCommand}, {{"delete_user_from_group", 0}, "delete_user_from_group uid gid", "Remove a user from a group", "Remove a user from a group.", &UserCommands::deleteUserFromGroupCommand}, + {{"set_password", "password", 0}, "set_password uid", "Set the password of a user", "Set the password of a user.", &UserCommands::setPasswordCommand}, {{"exit", "quit", 0}, "exit", "Close the connection and quit the client", "Close the connection and quit the client.", &CommandParser::exitCommand}, {{0}, 0, 0, 0, 0} }; diff --git a/src/Client/UserCommands.cpp b/src/Client/UserCommands.cpp index b93de94..21259d0 100644 --- a/src/Client/UserCommands.cpp +++ b/src/Client/UserCommands.cpp @@ -22,10 +22,10 @@ #include "CommandParser.h" #include <Common/RequestManager.h> - #include <Common/UserManager.h> #include <iostream> +#include <termios.h> namespace Mad { @@ -491,5 +491,67 @@ void UserCommands::deleteUserFromGroupCommand(CommandParser *commandParser, cons } } +void UserCommands::setPasswordCommand(CommandParser *commandParser, const std::vector<std::string> &args) { + if(args.size() < 2) { + std::cerr << args[0] << ": Too few arguments." << std::endl; + commandParser->printUsage("set_password"); + return; + } + if(args.size() > 2) { + std::cerr << args[0] << ": Too many arguments." << std::endl; + commandParser->printUsage("set_password"); + return; + } + + char *endptr; + unsigned long uid = std::strtoul(args[1].c_str(), &endptr, 10); + if(args[1].empty() || *endptr != '\0') { + std::cerr << args[0] << ": Unable to parse user id." << std::endl; + commandParser->printUsage("set_password"); + return; + } + + // TODO Extract this as a method + struct termios termold, termnew; + + if(tcgetattr(STDIN_FILENO, &termold) != 0) { + std::cerr << "Unable to set up terminal for password entry." << std::endl; + return; + } + + termnew = termold; + termnew.c_lflag &= ~ECHO; + if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &termnew) != 0) { + std::cerr << "Unable to set up terminal for password entry." << std::endl; + return; + } + + std::string password, password2; + + std::cout << "Password: " << std::flush; + std::getline(std::cin, password); + std::cout << std::endl; + + std::cout << "Verify password: " << std::flush; + std::getline(std::cin, password2); + std::cout << std::endl; + + tcsetattr(STDIN_FILENO, TCSAFLUSH, &termold); + + if(password != password2) { + std::cerr << "Passwords do not match." << std::endl; + return; + } + + try { + commandParser->application->getUserManager()->setPassword(uid, password); + + std::cout << "Password set." << std::endl; + } + catch(Core::Exception e) { + std::cerr << "An error occurred during your request: " << e.strerror() << "." << std::endl; + } +} + } } diff --git a/src/Client/UserCommands.h b/src/Client/UserCommands.h index 62d42c1..d5422da 100644 --- a/src/Client/UserCommands.h +++ b/src/Client/UserCommands.h @@ -52,6 +52,8 @@ class UserCommands { static void addUserToGroupCommand(CommandParser *commandParser, const std::vector<std::string> &args); static void deleteUserFromGroupCommand(CommandParser *commandParser, const std::vector<std::string> &args); + + static void setPasswordCommand(CommandParser *commandParser, const std::vector<std::string> &args); }; } diff --git a/src/Common/Backends/NetworkUserBackend.cpp b/src/Common/Backends/NetworkUserBackend.cpp index da964e7..00bd378 100644 --- a/src/Common/Backends/NetworkUserBackend.cpp +++ b/src/Common/Backends/NetworkUserBackend.cpp @@ -115,6 +115,15 @@ void NetworkUserBackend::UserGroupRequest::sendRequest() { sendPacket(packet); } +void NetworkUserBackend::PasswordRequest::sendRequest() { + XmlPacket packet; + packet.setType("SetPassword"); + packet.set("uid", uid); + packet.set("password", password); + + sendPacket(packet); +} + boost::shared_ptr<const std::map<unsigned long, UserInfo> > NetworkUserBackend::getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception) { application->getThreadManager()->detach(); @@ -397,11 +406,6 @@ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > NetworkUse } -/*void NetworkUserBackend::setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) { - -}*/ - - void NetworkUserBackend::checkUserInfo(const UserInfo &userInfo) throw(Core::Exception) { application->getThreadManager()->detach(); @@ -524,6 +528,19 @@ void NetworkUserBackend::deleteUserFromGroup(unsigned long uid, unsigned long gi throw result.second; } + +void NetworkUserBackend::setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) { + application->getThreadManager()->detach(); + + boost::shared_ptr<PasswordRequest> request(new PasswordRequest(application, uid, password)); + application->getRequestManager()->sendRequest(connection, request); + request->wait(); + + std::pair<boost::shared_ptr<const XmlPacket>, Core::Exception> result = request->getResult(); + if(!result.first || result.second) + throw result.second; +} + } } } diff --git a/src/Common/Backends/NetworkUserBackend.h b/src/Common/Backends/NetworkUserBackend.h index a3fa1a6..1ab0b58 100644 --- a/src/Common/Backends/NetworkUserBackend.h +++ b/src/Common/Backends/NetworkUserBackend.h @@ -137,6 +137,19 @@ class NetworkUserBackend : public UserDBBackend { : Request(application), type(type0), uid(uid0), gid(gid0) {} }; + class PasswordRequest : public Request { + private: + unsigned long uid; + std::string password; + + protected: + virtual void sendRequest(); + + public: + PasswordRequest(Application *application, unsigned long uid0, const std::string &password0) + : Request(application), uid(uid0), password(password0) {} + }; + static const std::string name; Application *application; @@ -155,8 +168,6 @@ class NetworkUserBackend : public UserDBBackend { virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception); - //virtual void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception); - virtual void checkUserInfo(const UserInfo &userInfo) throw(Core::Exception); virtual void addUser(const UserInfo &userInfo) throw(Core::Exception); virtual void updateUser(unsigned long uid, const Common::UserInfo &userInfo) throw(Core::Exception); @@ -170,6 +181,8 @@ class NetworkUserBackend : public UserDBBackend { virtual void addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception); virtual void deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception); + virtual void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception); + public: NetworkUserBackend(Application *application0, Connection *connection0) : application(application0), connection(connection0) {} diff --git a/src/Common/UserCache.h b/src/Common/UserCache.h index 1912caa..bec3328 100644 --- a/src/Common/UserCache.h +++ b/src/Common/UserCache.h @@ -70,11 +70,6 @@ class UserCache : public UserDBBackend, private boost::noncopyable { virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception); - virtual void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) { - backend->setPassword(uid, password); - } - - virtual void checkUserInfo(const UserInfo &userInfo) throw(Core::Exception) { backend->checkUserInfo(userInfo); } @@ -117,6 +112,11 @@ class UserCache : public UserDBBackend, private boost::noncopyable { backend->deleteUserFromGroup(uid, gid); } + + virtual void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) { + backend->setPassword(uid, password); + } + UserCache(Application *application0, boost::shared_ptr<UserDBBackend> backend0) : application(application0), backend(backend0), userTime(boost::posix_time::not_a_date_time), groupTime(boost::posix_time::not_a_date_time), userGroupTime(boost::posix_time::not_a_date_time) {} diff --git a/src/Common/UserConfigBackend.h b/src/Common/UserConfigBackend.h index 0c1f146..94550eb 100644 --- a/src/Common/UserConfigBackend.h +++ b/src/Common/UserConfigBackend.h @@ -36,18 +36,22 @@ class UserConfigBackend { virtual void checkUserInfo(const UserInfo& /*userInfo*/) throw(Core::Exception) {} - virtual void addUser(const UserInfo& /*userInfo*/) throw(Core::Exception) {} - virtual void updateUser(const UserInfo& /*oldUserInfo*/, const UserInfo& /*userInfo*/) throw(Core::Exception) {} - virtual void deleteUser(const UserInfo& /*userInfo*/) throw(Core::Exception) {} + virtual void addUser(const UserInfo &/*userInfo*/) throw(Core::Exception) {} + virtual void updateUser(const UserInfo &/*oldUserInfo*/, const UserInfo &/*userInfo*/) throw(Core::Exception) {} + virtual void deleteUser(const UserInfo &/*userInfo*/) throw(Core::Exception) {} - virtual void checkGroupInfo(const GroupInfo& /*groupInfo*/) throw(Core::Exception) {} + virtual void checkGroupInfo(const GroupInfo &/*groupInfo*/) throw(Core::Exception) {} - virtual void addGroup(const GroupInfo& /*groupInfo*/) throw(Core::Exception) {} - virtual void updateGroup(const GroupInfo& /*oldGroupInfo*/, const GroupInfo& /*groupInfo*/) throw(Core::Exception) {} - virtual void deleteGroup(const GroupInfo& /*groupInfo*/) throw(Core::Exception) {} + virtual void addGroup(const GroupInfo &/*groupInfo*/) throw(Core::Exception) {} + virtual void updateGroup(const GroupInfo &/*oldGroupInfo*/, const GroupInfo &/*groupInfo*/) throw(Core::Exception) {} + virtual void deleteGroup(const GroupInfo &/*groupInfo*/) throw(Core::Exception) {} - virtual void addUserToGroup(const UserInfo& /*userInfo*/, const GroupInfo& /*groupInfo*/) throw(Core::Exception) {} - virtual void deleteUserFromGroup(const UserInfo& /*userInfo*/, const GroupInfo& /*groupInfo*/) throw(Core::Exception) {} + virtual void addUserToGroup(const UserInfo &/*userInfo*/, const GroupInfo &/*groupInfo*/) throw(Core::Exception) {} + virtual void deleteUserFromGroup(const UserInfo &/*userInfo*/, const GroupInfo &/*groupInfo*/) throw(Core::Exception) {} + + virtual void setPassword(const Common::UserInfo &/*userInfo*/, const std::string &/*password*/) throw(Core::Exception) { + throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED)); + } }; } diff --git a/src/Common/UserDBBackend.h b/src/Common/UserDBBackend.h index 4a33f3a..664739c 100644 --- a/src/Common/UserDBBackend.h +++ b/src/Common/UserDBBackend.h @@ -85,11 +85,6 @@ class UserDBBackend { } - virtual void setPassword(unsigned long /*uid*/, const std::string& /*password*/) throw(Core::Exception) { - throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED)); - } - - virtual void checkUserInfo(const UserInfo& /*userInfo*/) throw(Core::Exception) {} virtual void addUser(const UserInfo& /*userInfo*/) throw(Core::Exception) { @@ -127,6 +122,11 @@ class UserDBBackend { throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED)); } + + virtual void setPassword(unsigned long /*uid*/, const std::string& /*password*/) throw(Core::Exception) { + throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED)); + } + public: virtual ~UserDBBackend() {} diff --git a/src/Common/UserManager.cpp b/src/Common/UserManager.cpp index bb4d205..d04a644 100644 --- a/src/Common/UserManager.cpp +++ b/src/Common/UserManager.cpp @@ -203,10 +203,6 @@ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > UserManage return dbBackend->getFullUserGroupList(timestamp); } -void UserManager::setPassword(unsigned long /*uid*/, const std::string& /*password*/) throw(Core::Exception) { - throw Core::Exception(Core::Exception::NOT_AVAILABLE); -} - void UserManager::checkUserInfo(const UserInfo &userInfo) throw(Core::Exception) { boost::shared_lock<boost::shared_mutex> lock(mutex); @@ -422,5 +418,44 @@ void UserManager::deleteUserFromGroup(unsigned long uid, unsigned long gid) thro } } +void UserManager::setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) { + boost::lock_guard<boost::shared_mutex> lock(mutex); + + if(!dbBackend) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + + boost::shared_ptr<const UserInfo> userInfo = dbBackend->getUserInfo(uid, 0); + if(!userInfo) + throw Core::Exception(Core::Exception::NOT_FOUND); + + bool ok = false; + Core::Exception exception; + + try { + dbBackend->setPassword(uid, password); + ok = true; + } + catch(Core::Exception e) { + exception = e; + + if(e.getErrorCode() != Core::Exception::NOT_IMPLEMENTED) + application->log(Core::LoggerBase::USER, Core::LoggerBase::WARNING, e.strerror()); + } + + for(std::set<boost::shared_ptr<UserConfigBackend> >::iterator configBackend = configBackends.begin(); configBackend != configBackends.end(); ++configBackend) { + try { + (*configBackend)->setPassword(*userInfo, password); + ok = true; + } + catch(Core::Exception e) { + if(e.getErrorCode() != Core::Exception::NOT_IMPLEMENTED) + application->log(Core::LoggerBase::USER, Core::LoggerBase::WARNING, e.strerror()); + } + } + + if(!ok) + throw exception; +} + } } diff --git a/src/Common/UserManager.h b/src/Common/UserManager.h index c70894a..b966662 100644 --- a/src/Common/UserManager.h +++ b/src/Common/UserManager.h @@ -115,8 +115,6 @@ class UserManager : public Core::Configurable, private boost::noncopyable { boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp = 0) throw(Core::Exception); - void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception); - void checkUserInfo(const UserInfo &userInfo) throw(Core::Exception); void addUser(const UserInfo &userInfo) throw(Core::Exception); void updateUser(unsigned long uid, const UserInfo &userInfo) throw(Core::Exception); @@ -129,6 +127,8 @@ class UserManager : public Core::Configurable, private boost::noncopyable { void addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception); void deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception); + + void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception); }; } diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp index c0de46a..a1aa829 100644 --- a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp +++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp @@ -331,6 +331,13 @@ void UserRequestHandlerGroup::handleDeleteUserFromGroupRequest(boost::shared_ptr ret->setType("OK"); } +void UserRequestHandlerGroup::handlePasswordSetRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, + Common::Connection* /*connection*/) { + application->getUserManager()->setPassword(packet->get<unsigned long>("uid"), packet->get<const std::string&>("password")); + + ret->setType("OK"); +} + UserRequestHandlerGroup::UserRequestHandlerGroup(Application *application0) : application(application0) { registerHandler("ListUsers", boost::bind(&UserRequestHandlerGroup::handleUserListRequest, this, _1, _2, _3)); registerHandler("GetUserInfo", boost::bind(&UserRequestHandlerGroup::handleUserInfoRequest, this, _1, _2, _3)); @@ -354,6 +361,8 @@ UserRequestHandlerGroup::UserRequestHandlerGroup(Application *application0) : ap registerHandler("AddUserToGroup", boost::bind(&UserRequestHandlerGroup::handleAddUserToGroupRequest, this, _1, _2, _3)); registerHandler("DeleteUserFromGroup", boost::bind(&UserRequestHandlerGroup::handleDeleteUserFromGroupRequest, this, _1, _2, _3)); + + registerHandler("SetPassword", boost::bind(&UserRequestHandlerGroup::handlePasswordSetRequest, this, _1, _2, _3)); } } diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.h b/src/Server/RequestHandlers/UserRequestHandlerGroup.h index c1338c4..ee4b7f4 100644 --- a/src/Server/RequestHandlers/UserRequestHandlerGroup.h +++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.h @@ -56,6 +56,8 @@ class UserRequestHandlerGroup : public Common::RequestHandlers::SimpleRequestHan void handleAddUserToGroupRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); void handleDeleteUserFromGroupRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); + void handlePasswordSetRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); + public: UserRequestHandlerGroup(Application *application0); }; diff --git a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp index 5a577ad..9a43691 100644 --- a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp +++ b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp @@ -19,6 +19,7 @@ #include "UserConfigBackendKrb5.h" #include <Core/ConfigEntry.h> +#include <Core/ThreadManager.h> #include <cstring> @@ -125,6 +126,8 @@ void UserConfigBackendKrb5::checkUserInfo(const Common::UserInfo &userInfo) thro } void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core::Exception) { + application->getThreadManager()->detach(); + std::string princStr = userInfo.getUsername() + "@" + realm; kadm5_principal_ent_rec princ; @@ -169,6 +172,8 @@ void UserConfigBackendKrb5::updateUser(const Common::UserInfo &oldUserInfo, cons } void UserConfigBackendKrb5::deleteUser(const Common::UserInfo &userInfo) throw(Core::Exception) { + application->getThreadManager()->detach(); + std::string princStr = userInfo.getUsername() + "@" + realm; krb5_principal princ; @@ -184,6 +189,24 @@ void UserConfigBackendKrb5::deleteUser(const Common::UserInfo &userInfo) throw(C // throw Core::Exception("kadm5_delete_principal", Core::Exception::INTERNAL_ERRNO, err); } +void UserConfigBackendKrb5::setPassword(const Common::UserInfo &userInfo, const std::string &password) throw(Core::Exception) { + application->getThreadManager()->detach(); + + std::string princStr = userInfo.getUsername() + "@" + realm; + krb5_principal princ; + + krb5_error_code err = krb5_parse_name(context, princStr.c_str(), &princ); + if(err) + throw Core::Exception("krb5_parse_name", Core::Exception::INTERNAL_ERRNO, err); + + err = kadm5_chpass_principal(handle, princ, const_cast<char*>(password.c_str())); + + krb5_free_principal(context, princ); + + if(err) + throw Core::Exception("kadm5_chpass_principal", Core::Exception::INTERNAL_ERRNO, err); +} + } } } diff --git a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h index afb7663..6571220 100644 --- a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h +++ b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h @@ -58,6 +58,8 @@ class UserConfigBackendKrb5 : public Common::UserConfigBackend, private Core::Co virtual void updateUser(const Common::UserInfo &oldUserInfo, const Common::UserInfo &userInfo) throw(Core::Exception); virtual void deleteUser(const Common::UserInfo &userInfo) throw(Core::Exception); + virtual void setPassword(const Common::UserInfo &userInfo, const std::string &password) throw(Core::Exception); + public: UserConfigBackendKrb5(Common::Application *application0) : application(application0), handle(0) { krb5_error_code err = krb5_init_context(&context); |