From fb74476cfac4d31753a311423d5778f5d58ef798 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Thu, 10 Oct 2013 14:43:58 +0200 Subject: [PATCH] Simple authentization: no credentials used and only current effective local user supported. --- src/CMakeLists.txt | 1 + src/Vfs.cpp | 11 ++- src/Vfs.h | 6 +- src/VfsAuthn.cpp | 280 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/VfsAuthn.h | 43 ++++++++ 5 files changed, 339 insertions(+), 2 deletions(-) create mode 100644 src/VfsAuthn.cpp create mode 100644 src/VfsAuthn.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c21c55..d4ee889 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required (VERSION 2.6) add_library (vfs MODULE Vfs.cpp + VfsAuthn.cpp VfsDriver.cpp VfsIO.cpp VfsNs.cpp diff --git a/src/Vfs.cpp b/src/Vfs.cpp index 7022f37..a31a8c9 100644 --- a/src/Vfs.cpp +++ b/src/Vfs.cpp @@ -8,6 +8,7 @@ #include #include "Vfs.h" +#include "VfsAuthn.h" #include "VfsDriver.h" #include "VfsIO.h" #include "VfsNs.h" @@ -106,10 +107,18 @@ IODriver* VfsFactory::createIODriver(PluginManager*) throw (DmException) +Authn* VfsFactory::createAuthn(PluginManager*) throw (DmException) +{ + return new VfsAuthn(); +} + + + static void registerPluginVfs(PluginManager* pm) throw(DmException) { VfsFactory* vfsFactory = new VfsFactory(); - + + pm->registerAuthnFactory(vfsFactory); pm->registerCatalogFactory(vfsFactory); pm->registerPoolManagerFactory(vfsFactory); pm->registerPoolDriverFactory(vfsFactory); diff --git a/src/Vfs.h b/src/Vfs.h index 93a3e32..6c6e1f2 100644 --- a/src/Vfs.h +++ b/src/Vfs.h @@ -25,7 +25,9 @@ namespace dmlite { /// Concrete factory for DPM wrapper class VfsFactory: public CatalogFactory, public IOFactory, - public PoolManagerFactory, public PoolDriverFactory { + public PoolManagerFactory, public PoolDriverFactory, + public AuthnFactory + { public: /// Constructor VfsFactory() throw (DmException); @@ -42,6 +44,8 @@ namespace dmlite { IODriver* createIODriver(PluginManager*) throw (DmException); + Authn* createAuthn(PluginManager *) throw (DmException); + protected: std::string hostName_; diff --git a/src/VfsAuthn.cpp b/src/VfsAuthn.cpp new file mode 100644 index 0000000..725eda7 --- /dev/null +++ b/src/VfsAuthn.cpp @@ -0,0 +1,280 @@ +#include +#include +#include +#include +#include +#include "Vfs.h" +#include "VfsAuthn.h" + +using namespace dmlite; + + + +VfsAuthn::VfsAuthn() throw (DmException) +{ + char buffer[1024]; + struct passwd pwd; + struct passwd *result; + uid_t uid; + + uid = geteuid(); + + if (getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result) != 0 || result == NULL) + vfsThrowErrno("current user not found (uid %d)", uid); + + this->currentUser = std::string(result->pw_name); + this->currentUid = uid; +} + + + +VfsAuthn::~VfsAuthn() +{ +} + + + +std::string VfsAuthn::getImplId() const throw () +{ + return "VfsAuthn"; +} + + + +SecurityContext *VfsAuthn::createSecurityContext(const SecurityCredentials &cred) throw (DmException) +{ + UserInfo user; + std::vector groups; + std::string userNameEmpty; + std::vector groupNamesEmpty; + + this->getIdMap(userNameEmpty, groupNamesEmpty, &user, &groups); + return new SecurityContext(cred, user, groups); +} + + + +void VfsAuthn::getIdMap(const std::string &userName, const std::vector &groupNames, UserInfo *user, std::vector *groups) throw (DmException) +{ + gid_t gid; + gid_t gids[20]; + int ngids, i; + UserInfo ui; + bool egid = false; + GroupInfo gi; + + ui["banned"] = 0; + ui["uid"] = this->currentUid; + ui.name = this->currentUser; + *user = ui; + + gid = getegid(); + ngids = getgroups(sizeof(gids)/sizeof(gid_t), gids); + wrapCall(ngids, "error getting current groups"); + + for (i = 0; i < ngids; i++) { + if (gids[i] == gid) egid = true; + gi = this->getGroup(gids[i]); + groups->push_back(gi); + } + if (!egid) { + gi = this->getGroup(gid); + groups->push_back(gi); + } +} + + + +GroupInfo VfsAuthn::newGroup(const std::string&) throw (DmException) +{ + vfsThrow(DMLITE_SYSERR(ENOSYS), "not supported in VfsAuthn"); +} + + + +GroupInfo VfsAuthn::getGroup(gid_t gid) throw (DmException) +{ + struct group grp; + struct group *result; + char buffer[1024]; + int res; + GroupInfo gi; + + res = getgrgid_r(gid, &grp, buffer, sizeof(buffer), &result); + + if (res != 0 || result == NULL) + vfsThrow(DMLITE_NO_SUCH_GROUP, "Group with id %d not found", gid); + + gi["banned"] = 0; + gi["gid"] = result->gr_gid; + gi.name = result->gr_name; + + return gi; +} + + + +GroupInfo VfsAuthn::getGroup(const std::string &groupName) throw (DmException) +{ + struct group grp; + struct group *result; + char buffer[1024]; + int res; + GroupInfo gi; + + res = getgrnam_r(groupName.c_str(), &grp, buffer, sizeof(buffer), &result); + + if (res != 0 || result == NULL) + vfsThrow(DMLITE_NO_SUCH_GROUP, "Group '%s' not found", groupName.c_str()); + + gi["banned"] = 0; + gi["gid"] = result->gr_gid; + gi.name = result->gr_name; + + return gi; +} + + + +GroupInfo VfsAuthn::getGroup(const std::string& key, + const boost::any& value) throw (DmException) +{ + if (key != "gid") + vfsThrow(DMLITE_SYSERR(DMLITE_UNKNOWN_KEY), + "VfsAuthn does not support querying by " + key); + + gid_t gid = Extensible::anyToUnsigned(value); + return this->getGroup(gid); +} + + + +std::vector VfsAuthn::getGroups(void) throw (DmException) +{ + std::vector groups; + GroupInfo group; + struct group* ent; + + setgrent(); + while ((ent = getgrent()) != NULL) { + group.clear(); + group.name = ent->gr_name; + group["gid"] = ent->gr_gid; + groups.push_back(group); + } + endgrent(); + + return groups; +} + + + +void VfsAuthn::updateGroup(const GroupInfo&) throw (DmException) +{ + vfsThrow(DMLITE_SYSERR(ENOSYS), "not supported in VfsAuthn"); +} + + + +void VfsAuthn::deleteGroup(const std::string&) throw (DmException) +{ + vfsThrow(DMLITE_SYSERR(ENOSYS), "not supported in VfsAuthn"); +} + + + +UserInfo VfsAuthn::newUser(const std::string&) throw (DmException) +{ + vfsThrow(DMLITE_SYSERR(ENOSYS), "not supported in VfsAuthn"); +} + + + +UserInfo VfsAuthn::getUser(const std::string& userName, gid_t* group) throw (DmException) +{ + struct passwd pwd; + struct passwd *result; + char buffer[1024]; + int res; + UserInfo ui; + + if (userName != this->currentUser) + vfsThrow(DMLITE_NO_SUCH_USER, "Only current effective local user is supported (%s)", this->currentUser.c_str()); + + res = getpwnam_r(userName.c_str(), &pwd, buffer, sizeof(buffer), &result); + + if (res != 0 || result == NULL) + vfsThrow(DMLITE_NO_SUCH_USER, "User '%s' not found", userName.c_str()); + + ui["banned"] = 0; + ui["uid"] = result->pw_uid; + ui.name = result->pw_name; + + *group = result->pw_gid; + + return ui; +} + + + +UserInfo VfsAuthn::getUser(const std::string& userName) throw (DmException) +{ + gid_t ignore; + return this->getUser(userName, &ignore); +} + + + +UserInfo VfsAuthn::getUser(const std::string& key, + const boost::any& value) throw (DmException) +{ + uid_t uid; + struct passwd pwdbuf, *upwd; + char buffer[512]; + int res; + UserInfo u; + + if (key != "uid") + vfsThrow(DMLITE_SYSERR(DMLITE_UNKNOWN_KEY), + "VfsAuthn does not support querying by " + key); + + uid = Extensible::anyToUnsigned(value); + if (uid != this->currentUid) + vfsThrow(DMLITE_NO_SUCH_USER, "Only current effective local user is supported (%s)", this->currentUser.c_str()); + + res = getpwuid_r(uid, &pwdbuf, buffer, sizeof(buffer), &upwd); + if (res != 0 || upwd == NULL) + vfsThrow(DMLITE_NO_SUCH_USER, "User with id %d not found", uid); + + u.name = upwd->pw_name; + u["uid"] = upwd->pw_uid; + return u; +} + + + +std::vector VfsAuthn::getUsers(void) throw (DmException) +{ + std::vector users; + UserInfo user; + + user.name = this->currentUser; + user["uid"] = this->currentUid; + users.push_back(user); + + return users; +} + + + +void VfsAuthn::updateUser(const UserInfo&) throw (DmException) +{ + vfsThrow(DMLITE_SYSERR(ENOSYS), "not supported in VfsAuthn"); +} + + + +void VfsAuthn::deleteUser(const std::string&) throw (DmException) +{ + vfsThrow(DMLITE_SYSERR(ENOSYS), "not supported in VfsAuthn"); +} diff --git a/src/VfsAuthn.h b/src/VfsAuthn.h new file mode 100644 index 0000000..6effb5d --- /dev/null +++ b/src/VfsAuthn.h @@ -0,0 +1,43 @@ +#ifndef VFSAUTHN_H +#define VFSAUTHN_H + +#include +#include + + +namespace dmlite { + + class VfsAuthn: public Authn + { + public: + VfsAuthn() throw (DmException); + ~VfsAuthn(); + + std::string getImplId(void) const throw (); + SecurityContext *createSecurityContext(const SecurityCredentials &cred) throw (DmException); + void getIdMap(const std::string &userName, const std::vector &groupNames, UserInfo *user, std::vector *groups) throw (DmException); + + GroupInfo newGroup(const std::string&) throw (DmException); + GroupInfo getGroup(gid_t gid) throw (DmException); + GroupInfo getGroup(const std::string &groupName) throw (DmException); + GroupInfo getGroup(const std::string& key, const boost::any& value) throw (DmException); + std::vector getGroups(void) throw (DmException); + void updateGroup(const GroupInfo&) throw (DmException); + void deleteGroup(const std::string&) throw (DmException); + + UserInfo newUser(const std::string&) throw (DmException); + UserInfo getUser(const std::string& userName, gid_t* group) throw (DmException); + UserInfo getUser(const std::string& userName) throw (DmException); + UserInfo getUser(const std::string& key, const boost::any& value) throw (DmException); + std::vector getUsers(void) throw (DmException); + void updateUser(const UserInfo&) throw (DmException); + void deleteUser(const std::string&) throw (DmException); + + protected: + uid_t currentUid; + std::string currentUser; + }; + +}; + +#endif -- 1.8.2.3