From 925949b2aa066d6c2486a9a52c8eb9e7f7479829 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 19 Oct 2013 21:55:18 +0200 Subject: [PATCH] Always preserve GID and UID, always reconstruct field list. --- src/VfsAuthn.cpp | 45 ++++++++++++++++++++++++++++++++++++++------- src/VfsAuthn.h | 2 +- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/VfsAuthn.cpp b/src/VfsAuthn.cpp index a3f3ea3..8ee6f45 100644 --- a/src/VfsAuthn.cpp +++ b/src/VfsAuthn.cpp @@ -224,7 +224,7 @@ void VfsAuthn::updateGroup(const GroupInfo& group) throw (DmException) // update local set of GIDs if needed gid = this->groups_[i].getUnsigned("gid"); newGid = group.getUnsigned("gid"); - if (gid != newGid) { + if (group.hasField("gid") && gid != newGid) { this->gids_.erase(gid); //not needed immediately: if (this->nextGid_ > gid) this->nextGid_ = gid; } @@ -233,6 +233,8 @@ void VfsAuthn::updateGroup(const GroupInfo& group) throw (DmException) debug("update group '%s', gid %u", group.name.c_str(), gid); this->groups_[i].clear(); this->groups_[i].copy(group); + if (!group.hasField("gid")) + this->groups_[i]["gid"] = gid; this->dirtyGroups_ = true; // save @@ -350,7 +352,7 @@ void VfsAuthn::updateUser(const UserInfo& user) throw (DmException) // update local set of UIDs if needed uid = this->users_[i].getUnsigned("uid"); newUid = user.getUnsigned("uid"); - if (uid != newUid) { + if (user.hasField("uid") && uid != newUid) { this->uids_.erase(uid); //not needed immediately: if (this->nextUid_ > uid) this->nextUid_ = uid; } @@ -359,6 +361,8 @@ void VfsAuthn::updateUser(const UserInfo& user) throw (DmException) debug("update user '%s', uid %u", user.name.c_str(), uid); this->users_[i].clear(); this->users_[i].copy(user); + if (!user.hasField("uid")) + this->users_[i]["uid"] = uid; this->dirtyUsers_ = true; // save @@ -414,11 +418,13 @@ static void csv_groups_load_entry(void *ctx, const Extensible& values) { void VfsAuthn::vfsLoad() throw (DmException) { + std::set userFields, groupFields; + // users this->users_.clear(); this->uids_.clear(); try { - csvLoad(VFS_USERS_FILE, (void *)&this->users_, this->userFields_, csv_users_load_entry); + csvLoad(VFS_USERS_FILE, (void *)&this->users_, userFields, csv_users_load_entry); } catch (DmException& e) { switch (e.code()) { case DMLITE_SYSERR(EIO): @@ -435,7 +441,7 @@ void VfsAuthn::vfsLoad() throw (DmException) { this->groups_.clear(); this->gids_.clear(); try { - csvLoad(VFS_GROUPS_FILE, (void *)&this->groups_, this->groupFields_, csv_groups_load_entry); + csvLoad(VFS_GROUPS_FILE, (void *)&this->groups_, groupFields, csv_groups_load_entry); } catch (DmException& e) { switch (e.code()) { case DMLITE_SYSERR(EIO): @@ -466,13 +472,19 @@ static bool csv_users_save_entry(void *ctx, size_t n, Extensible& values) { void VfsAuthn::vfsSaveUsers() throw (DmException) { + std::set fields; + if (this->noSync_) { this->dirtyUsers_ = true; return; } + // construct list of used fields + for (size_t i = 0; i < users_.size(); i++) + vfsRefreshFields(users_[i], fields); + try { - csvSave(VFS_USERS_FILE, (void *)&this->users_, this->userFields_, csv_users_save_entry); + csvSave(VFS_USERS_FILE, (void *)&this->users_, fields, csv_users_save_entry); } catch (DmException& e) { log(LOG_NOTICE, "could not create new version of users file in '%s'", this->prefix_.c_str()); this->dirtyUsers_ = true; @@ -499,13 +511,19 @@ static bool csv_groups_save_entry(void *ctx, size_t n, Extensible& values) { void VfsAuthn::vfsSaveGroups() throw (DmException) { + std::set fields; + if (this->noSync_) { this->dirtyGroups_ = true; return; } + // construct list of used fields + for (size_t i = 0; i < groups_.size(); i++) + vfsRefreshFields(groups_[i], fields); + try { - csvSave(VFS_GROUPS_FILE, (void *)&this->groups_, this->groupFields_, csv_groups_save_entry); + csvSave(VFS_GROUPS_FILE, (void *)&this->groups_, fields, csv_groups_save_entry); } catch (DmException& e) { log(LOG_NOTICE, "could not create new version of groups file in '%s'", this->prefix_.c_str()); this->dirtyGroups_ = true; @@ -619,10 +637,12 @@ void VfsAuthn::csvSave(std::string fileName, void *ctx, std::set& k /// -/// Helper function to check field names and contents in Extensible. +/// Helper function to check field names and contents in Extensible. Also update the fields set. +/// /// @param entity Entity ("user", "group") /// @param name User/group name /// @param data Checked data +/// @param fields Fields set to update // void VfsAuthn::vfsCheckInfo(const std::string& entity, const std::string& name, const Extensible data) throw (DmException) { std::vector keys; @@ -635,3 +655,14 @@ void VfsAuthn::vfsCheckInfo(const std::string& entity, const std::string& name, vfsThrow(DMLITE_SYSERR(EINVAL), "forbidden characters in %s data (user '%s', field '%s')", entity.c_str(), name.c_str(), keys[i].c_str()); } } + + + +void VfsAuthn::vfsRefreshFields(const Extensible& data, std::set& fields) { + std::vector keys; + + keys = data.getKeys(); + for (size_t i = 0; i < keys.size(); i++) { + fields.insert(keys[i]); + } +} diff --git a/src/VfsAuthn.h b/src/VfsAuthn.h index 7b9ca6a..82dc7b7 100644 --- a/src/VfsAuthn.h +++ b/src/VfsAuthn.h @@ -44,6 +44,7 @@ namespace dmlite { void vfsSaveGroups() throw (DmException); void vfsSaveUsers() throw (DmException); void vfsCheckInfo(const std::string& entity, const std::string& name, const Extensible data) throw (DmException); + void vfsRefreshFields(const Extensible& data, std::set& fields); void csvLoad(std::string fileName, void *ctx, std::set& keys, csv_load_entry_f *callback) throw (DmException); void csvSave(std::string fileName, void *ctx, std::set& keys, csv_save_entry_f *callback) throw (DmException); @@ -51,7 +52,6 @@ namespace dmlite { std::vector users_; std::vector groups_; std::set uids_, gids_; /// helper sets with UID/GID - std::set userFields_, groupFields_; /// all fields used in user/group info unsigned int nextUid_, nextGid_; /// next UID/GID after the one last inserted bool noSync_; /// saving users/groups disabled bool dirtyUsers_, dirtyGroups_; /// data needed to be saved -- 1.8.2.3