Always create at least one group - "nobody" with gid 65535 or higher.
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Thu, 28 Nov 2013 15:30:14 +0000 (16:30 +0100)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Fri, 21 Feb 2014 13:36:51 +0000 (14:36 +0100)
src/VfsAuthn.cpp
src/VfsAuthn.h

index d74c09f..4bedca3 100644 (file)
@@ -64,6 +64,7 @@ void VfsAuthn::getIdMap(const std::string &userName, const std::vector<std::stri
   UserInfo ui;
   GroupInfo gi;
   size_t ngroups;
+  gid_t gid;
 
   ui = this->newUser(userName);
   if (user) *user = ui;
@@ -79,6 +80,16 @@ void VfsAuthn::getIdMap(const std::string &userName, const std::vector<std::stri
     if (groups) groups->push_back(gi);
   }
 
+  // at least one group is required
+  if (groups && !groups->size()) {
+    // let initial gid for nodoby higher
+    gid = 65535;
+    while (this->gids_.find(gid) != this->gids_.end())
+      gid++;
+    gi = this->newGroup("nobody", gid);
+    if (groups) groups->push_back(gi);
+  }
+
   // bulk update
   this->noSync_ = false;
   if (ngroups != this->groups_.size() || this->dirtyGroups_)
@@ -87,7 +98,7 @@ void VfsAuthn::getIdMap(const std::string &userName, const std::vector<std::stri
 
 
 
-void VfsAuthn::vfsNewGroup(const std::string& groupName) throw (DmException) {
+void VfsAuthn::vfsNewGroup(const std::string& groupName, gid_t groupId) throw (DmException) {
   unsigned int gid;
   GroupInfo gi;
 
@@ -95,16 +106,20 @@ void VfsAuthn::vfsNewGroup(const std::string& groupName) throw (DmException) {
     vfsThrow(DMLITE_SYSERR(EINVAL), "group name can't contain tabelators or newline characters");
 
   // new gid
-  gid = this->nextGid_;
-  while (this->gids_.find(gid) != this->gids_.end())
-    gid++;
+  if (groupId == (gid_t)-1) {
+    gid = this->nextGid_;
+    while (this->gids_.find(gid) != this->gids_.end())
+      gid++;
+    this->nextGid_ = gid + 1;
+  } else {
+    gid = groupId;
+  }
 
   // insert
   gi.name = groupName;
   gi["gid"] = gid;
   this->groups_.push_back(gi);
   this->gids_.insert(gid);
-  this->nextGid_ = gid + 1;
   this->dirtyGroups_ = true;
 
   debug("new group '%s', gid %d", groupName.c_str(), gid);
@@ -154,6 +169,23 @@ GroupInfo VfsAuthn::newGroup(const std::string& groupName) throw (DmException)
 
 
 
+GroupInfo VfsAuthn::newGroup(const std::string& groupName, gid_t groupId) throw (DmException)
+{
+  size_t i;
+
+  for (i = 0; i < this->groups_.size(); i++)
+    if (this->groups_[i].name == groupName) break;
+
+  if (i >= this->groups_.size()) {
+    vfsNewGroup(groupName, groupId);
+    vfsSaveGroups();
+  }
+
+  return this->groups_[i];
+}
+
+
+
 GroupInfo VfsAuthn::getGroup(gid_t gid) throw (DmException)
 {
   size_t i;
index 82dc7b7..34e93f9 100644 (file)
@@ -28,6 +28,7 @@ namespace dmlite {
       std::vector<GroupInfo> getGroups(void) throw (DmException);
       void updateGroup(const GroupInfo&) throw (DmException);
       void deleteGroup(const std::string&) throw (DmException);
+      GroupInfo newGroup(const std::string& groupName, gid_t groupId) throw (DmException);
 
       UserInfo newUser(const std::string&) throw (DmException);
       UserInfo getUser(uid_t uid) throw (DmException);
@@ -38,7 +39,7 @@ namespace dmlite {
       void deleteUser(const std::string&) throw (DmException);
 
     protected:
-      void vfsNewGroup(const std::string& groupName) throw (DmException);
+      void vfsNewGroup(const std::string& groupName, gid_t groupId = (gid_t)-1) throw (DmException);
       void vfsNewUser(const std::string& userName) throw (DmException);
       void vfsLoad() throw (DmException);
       void vfsSaveGroups() throw (DmException);