Simple authentization: no credentials used and only current effective local user...
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 10 Oct 2013 12:43:58 +0000 (14:43 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 10 Oct 2013 12:43:58 +0000 (14:43 +0200)
src/CMakeLists.txt
src/Vfs.cpp
src/Vfs.h
src/VfsAuthn.cpp [new file with mode: 0644]
src/VfsAuthn.h [new file with mode: 0644]

index 7c21c55..d4ee889 100644 (file)
@@ -1,6 +1,7 @@
 cmake_minimum_required (VERSION 2.6)
 
 add_library (vfs MODULE Vfs.cpp
+                        VfsAuthn.cpp
                         VfsDriver.cpp
                         VfsIO.cpp
                         VfsNs.cpp
index 7022f37..a31a8c9 100644 (file)
@@ -8,6 +8,7 @@
 #include <sys/utsname.h>
 
 #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);
index 93a3e32..6c6e1f2 100644 (file)
--- 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 (file)
index 0000000..725eda7
--- /dev/null
@@ -0,0 +1,280 @@
+#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <dmlite/cpp/dmlite.h>
+#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<GroupInfo> groups;
+  std::string userNameEmpty;
+  std::vector<std::string> groupNamesEmpty;
+
+  this->getIdMap(userNameEmpty, groupNamesEmpty, &user, &groups);
+  return new SecurityContext(cred, user, groups);
+}
+
+
+
+void VfsAuthn::getIdMap(const std::string &userName, const std::vector<std::string> &groupNames, UserInfo *user, std::vector<GroupInfo> *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<GroupInfo> VfsAuthn::getGroups(void) throw (DmException)
+{
+  std::vector<GroupInfo> 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<UserInfo> VfsAuthn::getUsers(void) throw (DmException)
+{
+  std::vector<UserInfo> 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 (file)
index 0000000..6effb5d
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef VFSAUTHN_H
+#define VFSAUTHN_H
+
+#include <sys/types.h>
+#include <dmlite/cpp/authn.h>
+
+
+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<std::string> &groupNames, UserInfo *user, std::vector<GroupInfo> *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<GroupInfo> 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<UserInfo> 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