summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-07-17 19:00:40 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-07-17 19:00:40 +0200
commitfdd7fbae926821be7d5229d5cba04396e6f00f99 (patch)
tree73edc33360d5f83f0a62b1f1a5b89c4b9b5e9e07
parentdf114cc52f48645c9c6736faceef8920c9441cbe (diff)
downloadmad-fdd7fbae926821be7d5229d5cba04396e6f00f99.tar
mad-fdd7fbae926821be7d5229d5cba04396e6f00f99.zip
UserBackendHome hinzugefügt
Modul zur Erstellung von Home-Verzeichnissen implementert
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/mad-server.conf5
-rw-r--r--src/mad-server.cpp1
-rw-r--r--src/modules/CMakeLists.txt1
-rw-r--r--src/modules/UserBackendHome/CMakeLists.txt8
-rw-r--r--src/modules/UserBackendHome/Module.cpp28
-rw-r--r--src/modules/UserBackendHome/Module.h52
-rw-r--r--src/modules/UserBackendHome/UserBackendHome.cpp195
-rw-r--r--src/modules/UserBackendHome/UserBackendHome.h69
9 files changed, 360 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d884224..8da14e2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ find_package(DL REQUIRED)
find_package(Readline REQUIRED)
#find_package(KRB5 REQUIRED gssapi)
find_package(OpenSSL REQUIRED)
-find_package(Boost REQUIRED date_time regex signals system thread)
+find_package(Boost REQUIRED date_time filesystem regex signals system thread)
find_package(MySQL)
configure_file(${MAD_SOURCE_DIR}/config.h.in ${MAD_BINARY_DIR}/config.h)
diff --git a/src/mad-server.conf b/src/mad-server.conf
index 76533cf..41aa298 100644
--- a/src/mad-server.conf
+++ b/src/mad-server.conf
@@ -33,6 +33,11 @@ UserBackendMysql {
}
}
+UserBackendHome {
+ HomeDir "/tmp/home"
+ Skeleton "/tmp/skel"
+}
+
Daemon test {
IpAddress 127.0.0.1
}
diff --git a/src/mad-server.cpp b/src/mad-server.cpp
index 870567f..1749ba2 100644
--- a/src/mad-server.cpp
+++ b/src/mad-server.cpp
@@ -33,6 +33,7 @@ int main() {
application.getModuleManager()->loadModule("SystemBackendProc");
application.getModuleManager()->loadModule("UserBackendMysql");
+ application.getModuleManager()->loadModule("UserBackendHome");
application.getConfigManager()->loadFile("mad-server.conf");
application.getConfigManager()->finish();
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
index fb9aac0..774b4eb 100644
--- a/src/modules/CMakeLists.txt
+++ b/src/modules/CMakeLists.txt
@@ -34,6 +34,7 @@ endmacro(mad_module_libraries)
add_subdirectory(FileLogger)
add_subdirectory(SystemBackendPosix)
add_subdirectory(SystemBackendProc)
+add_subdirectory(UserBackendHome)
if(MYSQL_FOUND)
add_subdirectory(UserBackendMysql)
diff --git a/src/modules/UserBackendHome/CMakeLists.txt b/src/modules/UserBackendHome/CMakeLists.txt
new file mode 100644
index 0000000..9d053f3
--- /dev/null
+++ b/src/modules/UserBackendHome/CMakeLists.txt
@@ -0,0 +1,8 @@
+include_directories(${INCLUDES})
+
+mad_module(UserBackendHome
+ Module.cpp Module.h
+ UserBackendHome.cpp UserBackendHome.h
+)
+
+mad_module_libraries(UserBackendHome) \ No newline at end of file
diff --git a/src/modules/UserBackendHome/Module.cpp b/src/modules/UserBackendHome/Module.cpp
new file mode 100644
index 0000000..b6a1052
--- /dev/null
+++ b/src/modules/UserBackendHome/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* UserBackendHome_create(Mad::Common::Application *application) {
+ return new Mad::Modules::UserBackendHome::Module(application);
+}
+
+}
diff --git a/src/modules/UserBackendHome/Module.h b/src/modules/UserBackendHome/Module.h
new file mode 100644
index 0000000..da384bc
--- /dev/null
+++ b/src/modules/UserBackendHome/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_USERBACKENDHOME_MODULE_H_
+#define MAD_MODULES_USERBACKENDHOME_MODULE_H_
+
+#include "UserBackendHome.h"
+
+#include <Common/Module.h>
+#include <Common/UserManager.h>
+
+namespace Mad {
+namespace Modules {
+namespace UserBackendHome {
+
+class Module : public Common::Module {
+ private:
+ Common::Application *application;
+
+ boost::shared_ptr<UserBackendHome> backend;
+
+ public:
+ Module(Common::Application *application0) : application(application0), backend(new UserBackendHome(application)) {
+ application->getUserManager()->registerBackend(backend);
+ }
+
+ virtual ~Module() {
+ application->getUserManager()->unregisterBackend(backend);
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_MODULES_USERBACKENDHOME_MODULE_H_ */
diff --git a/src/modules/UserBackendHome/UserBackendHome.cpp b/src/modules/UserBackendHome/UserBackendHome.cpp
new file mode 100644
index 0000000..d524a52
--- /dev/null
+++ b/src/modules/UserBackendHome/UserBackendHome.cpp
@@ -0,0 +1,195 @@
+/*
+ * UserBackendHome.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 "UserBackendHome.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 UserBackendHome {
+
+bool UserBackendHome::handleConfigEntry(const Core::ConfigEntry &entry, bool handled) {
+ if(handled)
+ return false;
+
+ if(entry[0].getKey().matches("UserBackendHome")) {
+ 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].empty())
+ return false;
+
+ return true;
+ }
+
+ return false;
+}
+
+void UserBackendHome::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 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 UserBackendHome::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
+ }
+
+ 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 UserBackendHome::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 UserBackendHome::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/UserBackendHome/UserBackendHome.h b/src/modules/UserBackendHome/UserBackendHome.h
new file mode 100644
index 0000000..1e2b0a3
--- /dev/null
+++ b/src/modules/UserBackendHome/UserBackendHome.h
@@ -0,0 +1,69 @@
+/*
+ * UserBackendMysql.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_USERBACKENDHOME_USERBACKENDHOME_H_
+#define MAD_MODULES_USERBACKENDHOME_USERBACKENDHOME_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 UserBackendHome {
+
+class UserBackendHome : public Common::UserConfigBackend, private Core::Configurable, private boost::noncopyable {
+ private:
+ Common::Application *application;
+
+ std::string skeleton;
+ std::string homeDir;
+
+ 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:
+ UserBackendHome(Common::Application *application0) : application(application0), homeDir("/home") {
+ application->getConfigManager()->registerConfigurable(this);
+ }
+
+ virtual ~UserBackendHome() {
+ application->getConfigManager()->unregisterConfigurable(this);
+ }
+};
+
+}
+}
+}
+
+#endif /* MAD_MODULES_USERBACKENDHOME_USERBACKENDHOME_H_ */