--- /dev/null
+#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");
+}
--- /dev/null
+#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