// 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;
}
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
// 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;
}
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
void VfsAuthn::vfsLoad() throw (DmException) {
+ std::set<std::string> 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):
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):
void VfsAuthn::vfsSaveUsers() throw (DmException) {
+ std::set<std::string> 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;
void VfsAuthn::vfsSaveGroups() throw (DmException) {
+ std::set<std::string> 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;
///
-/// 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<std::string> keys;
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<std::string>& fields) {
+ std::vector<std::string> keys;
+
+ keys = data.getKeys();
+ for (size_t i = 0; i < keys.size(); i++) {
+ fields.insert(keys[i]);
+ }
+}
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<std::string>& fields);
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);
std::vector<UserInfo> users_;
std::vector<GroupInfo> groups_;
std::set<unsigned int> uids_, gids_; /// helper sets with UID/GID
- std::set<std::string> 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