Implement updateUser()/updateGroup().
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Sat, 19 Oct 2013 19:17:30 +0000 (21:17 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Fri, 21 Feb 2014 13:36:48 +0000 (14:36 +0100)
src/VfsAuthn.cpp
src/VfsAuthn.h

index 498b925..a3f3ea3 100644 (file)
@@ -206,9 +206,37 @@ std::vector<GroupInfo> VfsAuthn::getGroups(void) throw (DmException)
 
 
 
-void VfsAuthn::updateGroup(const GroupInfo&) throw (DmException)
+void VfsAuthn::updateGroup(const GroupInfo& group) throw (DmException)
 {
-  vfsThrow(DMLITE_SYSERR(ENOSYS), "not supported in VfsAuthn");
+  size_t i;
+  gid_t gid, newGid;
+
+  // check content
+  vfsCheckInfo("group", group.name, group);
+
+  // find
+  for (i = 0; i < this->groups_.size(); i++)
+    if (this->groups_[i].name == group.name) break;
+
+  if (i >= this->groups_.size())
+    return;
+
+  // update local set of GIDs if needed
+  gid = this->groups_[i].getUnsigned("gid");
+  newGid = group.getUnsigned("gid");
+  if (gid != newGid) {
+    this->gids_.erase(gid);
+    //not needed immediately: if (this->nextGid_ > gid) this->nextGid_ = gid;
+  }
+
+  // update group
+  debug("update group '%s', gid %u", group.name.c_str(), gid);
+  this->groups_[i].clear();
+  this->groups_[i].copy(group);
+  this->dirtyGroups_ = true;
+
+  // save
+  vfsSaveGroups();
 }
 
 
@@ -304,9 +332,37 @@ std::vector<UserInfo> VfsAuthn::getUsers(void) throw (DmException)
 
 
 
-void VfsAuthn::updateUser(const UserInfo&) throw (DmException)
+void VfsAuthn::updateUser(const UserInfo& user) throw (DmException)
 {
-  vfsThrow(DMLITE_SYSERR(ENOSYS), "not supported in VfsAuthn");
+  size_t i;
+  uid_t uid, newUid;
+
+  // check content
+  vfsCheckInfo("user", user.name, user);
+
+  // find
+  for (i = 0; i < this->users_.size(); i++)
+    if (this->users_[i].name == user.name) break;
+
+  if (i >= this->users_.size())
+    return;
+
+  // update local set of UIDs if needed
+  uid = this->users_[i].getUnsigned("uid");
+  newUid = user.getUnsigned("uid");
+  if (uid != newUid) {
+    this->uids_.erase(uid);
+    //not needed immediately: if (this->nextUid_ > uid) this->nextUid_ = uid;
+  }
+
+  // update user
+  debug("update user '%s', uid %u", user.name.c_str(), uid);
+  this->users_[i].clear();
+  this->users_[i].copy(user);
+  this->dirtyUsers_ = true;
+
+  // save
+  vfsSaveUsers();
 }
 
 
@@ -559,3 +615,23 @@ void VfsAuthn::csvSave(std::string fileName, void *ctx, std::set<std::string>& k
   if (rename(newPath.c_str(), path.c_str()) == -1)
     throw DmException(errno, "could not save file '%s'", path.c_str());
 }
+
+
+
+///
+/// Helper function to check field names and contents in Extensible.
+/// @param entity Entity ("user", "group")
+/// @param name   User/group name
+/// @param data   Checked data
+//
+void VfsAuthn::vfsCheckInfo(const std::string& entity, const std::string& name, const Extensible data) throw (DmException) {
+  std::vector<std::string> keys;
+
+  keys = data.getKeys();
+  for (size_t i = 0; i < keys.size(); i++) {
+    if (keys[i].find_first_of("\t\n\r") != std::string::npos)
+      vfsThrow(DMLITE_SYSERR(EINVAL), "forbidden character in %s field names (user '%s', field '%s')", entity.c_str(), name.c_str(), keys[i].c_str());
+    if (data.getString(keys[i]).find_first_of("\t\n\r") != std::string::npos)
+      vfsThrow(DMLITE_SYSERR(EINVAL), "forbidden characters in %s data (user '%s', field '%s')", entity.c_str(), name.c_str(), keys[i].c_str());
+  }
+}
index e557e3c..7b9ca6a 100644 (file)
@@ -43,6 +43,7 @@ namespace dmlite {
       void vfsLoad() throw (DmException);
       void vfsSaveGroups() throw (DmException);
       void vfsSaveUsers() throw (DmException);
+      void vfsCheckInfo(const std::string& entity, const std::string& name, const Extensible data) throw (DmException);
       void csvLoad(std::string fileName, void *ctx, std::set<std::string>& keys, csv_load_entry_f *callback) throw (DmException);
       void csvSave(std::string fileName, void *ctx, std::set<std::string>& keys, csv_save_entry_f *callback) throw (DmException);