summaryrefslogtreecommitdiffstats
path: root/src/modules/UserConfigBackendHome
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/UserConfigBackendHome')
-rw-r--r--src/modules/UserConfigBackendHome/CMakeLists.txt8
-rw-r--r--src/modules/UserConfigBackendHome/Module.cpp28
-rw-r--r--src/modules/UserConfigBackendHome/Module.h52
-rw-r--r--src/modules/UserConfigBackendHome/UserConfigBackendHome.cpp213
-rw-r--r--src/modules/UserConfigBackendHome/UserConfigBackendHome.h70
5 files changed, 371 insertions, 0 deletions
diff --git a/src/modules/UserConfigBackendHome/CMakeLists.txt b/src/modules/UserConfigBackendHome/CMakeLists.txt
new file mode 100644
index 0000000..4f8e224
--- /dev/null
+++ b/src/modules/UserConfigBackendHome/CMakeLists.txt
@@ -0,0 +1,8 @@
+include_directories(${INCLUDES})
+
+mad_module(UserConfigBackendHome
+ Module.cpp Module.h
+ UserConfigBackendHome.cpp UserConfigBackendHome.h
+)
+
+mad_module_libraries(UserConfigBackendHome) \ No newline at end of file
diff --git a/src/modules/UserConfigBackendHome/Module.cpp b/src/modules/UserConfigBackendHome/Module.cpp
new file mode 100644
index 0000000..cab1b80
--- /dev/null
+++ b/src/modules/UserConfigBackendHome/Module.cpp
@@ -0,0 +1,28 @@
+/*
+ * Module.cpp
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Module.h"
+
+extern "C" {
+
+Mad::Common::Module* UserConfigBackendHome_create(Mad::Common::Application *application) {
+ return new Mad::Modules::UserConfigBackendHome::Module(application);
+}
+
+}
diff --git a/src/modules/UserConfigBackendHome/Module.h b/src/modules/UserConfigBackendHome/Module.h
new file mode 100644
index 0000000..1d6322d
--- /dev/null
+++ b/src/modules/UserConfigBackendHome/Module.h
@@ -0,0 +1,52 @@
+/*
+ * Module.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_MODULES_USERCONFIGBACKENDHOME_MODULE_H_
+#define MAD_MODULES_USERCONFIGBACKENDHOME_MODULE_H_
+
+#include "UserConfigBackendHome.h"
+
+#include <Common/Module.h>
+#include <Common/UserManager.h>
+
+namespace Mad {
+namespace Modules {
+namespace UserConfigBackendHome {
+
+class Module : public Common::Module {
+ private:
+ Common::Application *application;
+
+ boost::shared_ptr<UserConfigBackendHome> backend;
+
+ public:
+ Module(Common::Application *application0) : application(application0), backend(new UserConfigBackendHome(application)) {
+ application->getUserManager()->registerBackend(backend);
+ }
+
+ virtual ~Module() {
+ application->getUserManager()->unregisterBackend(backend);
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_MODULES_USERCONFIGBACKENDHOME_MODULE_H_ */
diff --git a/src/modules/UserConfigBackendHome/UserConfigBackendHome.cpp b/src/modules/UserConfigBackendHome/UserConfigBackendHome.cpp
new file mode 100644
index 0000000..b68268b
--- /dev/null
+++ b/src/modules/UserConfigBackendHome/UserConfigBackendHome.cpp
@@ -0,0 +1,213 @@
+/*
+ * UserConfigBackendHome.cpp
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "UserConfigBackendHome.h"
+#include <Core/ConfigEntry.h>
+#include <Core/ConfigManager.h>
+
+#include <boost/filesystem.hpp>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+namespace Mad {
+namespace Modules {
+namespace UserConfigBackendHome {
+
+bool UserConfigBackendHome::handleConfigEntry(const Core::ConfigEntry &entry, bool /*handled*/) {
+ if(entry[0].getKey().matches("UserManager")) {
+ if(entry[1].getKey().matches("Skeleton")) {
+ if(entry[2].empty())
+ skeleton = entry[1][0];
+ }
+ else if(entry[1].getKey().matches("HomeDir")) {
+ if(entry[2].empty())
+ homeDir = entry[1][0];
+ }
+ else if(entry[1].getKey().matches("UserDirMode")) {
+ if(entry[2].empty()) {
+ if(entry[1][0].empty()) {
+ dirMode = 0755;
+ }
+ else {
+ char *endptr;
+ unsigned long val = std::strtoul(entry[1][0].c_str(), &endptr, 8);
+ if(*endptr || val > 07777) {
+ application->logf(Core::LoggerBase::WARNING, "UserBackendHome: Invalid configuration: DirMode '%s'", entry[1][0].c_str());
+ }
+ else {
+ dirMode = val;
+ }
+ }
+ }
+ }
+ else if(!entry[1].empty())
+ return false;
+
+ return true;
+ }
+
+ return false;
+}
+
+void UserConfigBackendHome::setOwnerAndCopyMode(const std::string &source, const std::string &dest, const Common::UserInfo &userInfo, bool isSymlink) {
+ if((isSymlink ? lchown : chown)(dest.c_str(), (uid_t)userInfo.getUid(), (gid_t)userInfo.getGid()) != 0) {
+ // TODO Error
+ }
+
+ struct stat st;
+ if((isSymlink ? lstat : stat)(source.c_str(), &st) == 0) {
+ if((isSymlink ? lchmod : chmod)(dest.c_str(), st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != 0) {
+ // TODO Error
+ }
+ }
+}
+
+void UserConfigBackendHome::migrateOwner(const std::string &path, const Common::UserInfo &oldUserInfo, const Common::UserInfo &userInfo, bool isSymlink) {
+ struct stat st;
+ if((isSymlink ? lstat : stat)(path.c_str(), &st) != 0) {
+ // TODO Error
+ return;
+ }
+
+ uid_t uid = -1;
+ gid_t gid = -1;
+
+ if(st.st_uid == oldUserInfo.getUid())
+ uid = (uid_t)userInfo.getUid();
+
+ if(st.st_gid == oldUserInfo.getGid())
+ gid = (gid_t)userInfo.getGid();
+
+ if(uid != (uid_t)-1 || gid != (gid_t)-1) {
+ if((isSymlink ? lchown : chown)(path.c_str(), uid, gid) != 0) {
+ // TODO Error
+ }
+ }
+}
+
+void UserConfigBackendHome::addUser(const Common::UserInfo &userInfo) throw(Core::Exception) {
+ boost::filesystem::path path(homeDir);
+ path /= userInfo.getUsername();
+
+ boost::filesystem::create_directories(path);
+
+ std::string nativePath = path.directory_string();
+ if(chown(nativePath.c_str(), (uid_t)userInfo.getUid(), (gid_t)userInfo.getGid()) != 0) {
+ // TODO Error
+ }
+
+ if(chmod(nativePath.c_str(), (mode_t)dirMode)) {
+ // TODO Error
+ }
+
+ boost::filesystem::path skeletonPath(skeleton);
+ if(!boost::filesystem::is_directory(skeletonPath))
+ return;
+
+ boost::filesystem::path oldPath = boost::filesystem::current_path();
+ boost::filesystem::current_path(skeletonPath);
+
+ boost::filesystem::recursive_directory_iterator end;
+
+ for(boost::filesystem::recursive_directory_iterator it("."); it != end; ++it) {
+ boost::filesystem::path source = it->path();
+ boost::filesystem::path dest = path / source;
+
+ try {
+ if(boost::filesystem::is_symlink(it->symlink_status())) {
+ it.no_push();
+
+ std::string sourceStr = source.file_string();
+
+ char link[PATH_MAX];
+ int ret = ::readlink(sourceStr.c_str(), link, PATH_MAX);
+ if(ret <= 0)
+ continue;
+
+ boost::filesystem::create_symlink(boost::filesystem::path(std::string(link, ret)), dest);
+ setOwnerAndCopyMode(sourceStr, dest.file_string(), userInfo, true);
+ }
+ else if(boost::filesystem::is_directory(it->status())) {
+ boost::filesystem::create_directory(dest);
+ setOwnerAndCopyMode(source.directory_string(), dest.directory_string(), userInfo, false);
+ }
+ else {
+ boost::filesystem::copy_file(source, dest);
+ setOwnerAndCopyMode(source.file_string(), dest.file_string(), userInfo, false);
+ }
+ }
+ catch(...) {}
+ }
+
+ boost::filesystem::current_path(oldPath);
+}
+
+void UserConfigBackendHome::updateUser(const Common::UserInfo &oldUserInfo, const Common::UserInfo &userInfo) throw(Core::Exception) {
+ boost::filesystem::path oldPath(homeDir);
+ oldPath /= oldUserInfo.getUsername();
+
+ boost::filesystem::path path(homeDir);
+ path /= userInfo.getUsername();
+
+ if(oldPath != path) {
+ try {
+ boost::filesystem::rename(oldPath, path);
+ }
+ catch(...) {
+ return;
+ }
+ }
+
+ if(oldUserInfo.getUid() == userInfo.getUid() && oldUserInfo.getGid() == userInfo.getGid())
+ return;
+
+ std::string nativePath = path.directory_string();
+ if(chown(nativePath.c_str(), (uid_t)userInfo.getUid(), (gid_t)userInfo.getGid()) != 0) {
+ // TODO Error
+ }
+
+ boost::filesystem::recursive_directory_iterator end;
+
+ for(boost::filesystem::recursive_directory_iterator it(path); it != end; ++it) {
+ if(boost::filesystem::is_symlink(it->symlink_status())) {
+ it.no_push();
+
+ migrateOwner(it->path().file_string(), oldUserInfo, userInfo, true);
+ }
+ else if(boost::filesystem::is_directory(it->status())) {
+ migrateOwner(it->path().directory_string(), oldUserInfo, userInfo, false);
+ }
+ else {
+ migrateOwner(it->path().file_string(), oldUserInfo, userInfo, false);
+ }
+ }
+}
+
+void UserConfigBackendHome::deleteUser(const Common::UserInfo &userInfo) throw(Core::Exception) {
+ boost::filesystem::path path(homeDir);
+ path /= userInfo.getUsername();
+
+ boost::filesystem::remove_all(path);
+}
+
+}
+}
+}
diff --git a/src/modules/UserConfigBackendHome/UserConfigBackendHome.h b/src/modules/UserConfigBackendHome/UserConfigBackendHome.h
new file mode 100644
index 0000000..f115d9e
--- /dev/null
+++ b/src/modules/UserConfigBackendHome/UserConfigBackendHome.h
@@ -0,0 +1,70 @@
+/*
+ * UserConfigBackendMysql.h
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_MODULES_USERCONFIGBACKENDHOME_USERCONFIGBACKENDHOME_H_
+#define MAD_MODULES_USERCONFIGBACKENDHOME_USERCONFIGBACKENDHOME_H_
+
+#include <Common/UserConfigBackend.h>
+#include <Common/Application.h>
+
+#include <Core/Configurable.h>
+#include <Core/ConfigManager.h>
+
+#include <boost/thread/mutex.hpp>
+
+namespace Mad {
+namespace Modules {
+namespace UserConfigBackendHome {
+
+class UserConfigBackendHome : public Common::UserConfigBackend, private Core::Configurable, private boost::noncopyable {
+ private:
+ Common::Application *application;
+
+ std::string skeleton;
+ std::string homeDir;
+ unsigned long dirMode;
+
+ boost::mutex mutex;
+
+ void setOwnerAndCopyMode(const std::string &source, const std::string &dest, const Common::UserInfo &userInfo, bool isSymlink);
+
+ void migrateOwner(const std::string &path, const Common::UserInfo &oldUserInfo, const Common::UserInfo &userInfo, bool isSymlink);
+
+ protected:
+ virtual bool handleConfigEntry(const Core::ConfigEntry &entry, bool handled);
+
+ virtual void addUser(const Common::UserInfo &userInfo) throw(Core::Exception);
+ virtual void updateUser(const Common::UserInfo &oldUserInfo, const Common::UserInfo &userInfo) throw(Core::Exception);
+ virtual void deleteUser(const Common::UserInfo &userInfo) throw(Core::Exception);
+
+ public:
+ UserConfigBackendHome(Common::Application *application0) : application(application0), homeDir("/home"), dirMode(0755) {
+ application->getConfigManager()->registerConfigurable(this);
+ }
+
+ virtual ~UserConfigBackendHome() {
+ application->getConfigManager()->unregisterConfigurable(this);
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_MODULES_USERCONFIGBACKENDHOME_USERCONFIGBACKENDHOME_H_ */