Loading src/authdb.cpp +28 −25 Original line number Diff line number Diff line Loading @@ -655,30 +655,7 @@ int main(int argc,char *argv[]){ key ); /* Drop privileges after binding HTTP socket */ #ifndef _WIN32 if (getuid() == 0) { struct passwd *pw = getpwnam("authdb"); if (pw) { if (setgid(pw->pw_gid) != 0) { std::cerr << "setgid failed" << std::endl; return 1; } if (initgroups("authdb", pw->pw_gid) != 0) { std::cerr << "initgroups failed" << std::endl; return 1; } if (setuid(pw->pw_uid) != 0) { std::cerr << "setuid failed" << std::endl; return 1; } } else { std::cerr << "user authdb not found, running as root" << std::endl; } } #endif /* Start cluster after priv drop so all files are owned by authdb */ /* Start cluster while still root so QUIC can bind privileged ports */ if (clusterEnabled) { cluster.init(ccfg); cluster.start(); Loading Loading @@ -764,7 +741,33 @@ int main(int argc,char *argv[]){ authdb::g_KdcPlugin = pluginMgr.getPlugin<authdb::KdcPlugin>("krb5"); authdb::g_AdPlugin = pluginMgr.getPlugin<authdb::AdPlugin>("ad"); /* Start each plugin in its own background thread */ /* Init plugins while still root — bind privileged ports (88, 389, etc.) */ pluginMgr.initAll(); /* Drop privileges after all sockets are bound */ #ifndef _WIN32 if (getuid() == 0) { struct passwd *pw = getpwnam("authdb"); if (pw) { if (setgid(pw->pw_gid) != 0) { std::cerr << "setgid failed" << std::endl; return 1; } if (initgroups("authdb", pw->pw_gid) != 0) { std::cerr << "initgroups failed" << std::endl; return 1; } if (setuid(pw->pw_uid) != 0) { std::cerr << "setuid failed" << std::endl; return 1; } } else { std::cerr << "user authdb not found, running as root" << std::endl; } } #endif /* Start each plugin in its own background thread (runs as unprivileged user) */ std::vector<std::thread> pluginThreads; for (auto &[pname, lp] : pluginMgr.plugins()) { pluginThreads.emplace_back([&lp, &pname](){ Loading src/plugin.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -188,4 +188,17 @@ int PluginManager::loadAll(const std::string &directory, return loaded; } void PluginManager::initAll() { for (auto &[name, lp] : _Plugins) { if (lp.instance) { try { lp.instance->init(); } catch (const std::exception &e) { std::cerr << "Plugin init failed: " << name << ": " << e.what() << std::endl; } } } } } /* namespace authdb */ src/plugin.h +7 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,10 @@ namespace authdb { /* Human-readable name, e.g. "krb5", "ldap" */ virtual const char *name() const = 0; /* Bind sockets and acquire resources that require root. * Called before privilege drop. Default: no-op. */ virtual void init() {} /* Start the plugin (blocking – caller runs this in a thread) */ virtual void run() = 0; }; Loading Loading @@ -117,6 +121,9 @@ namespace authdb { AuthBackend &backend, const char *configJson = "{}"); /* Call init() on every loaded plugin (while still root) */ void initAll(); /* Retrieve a plugin by name, dynamically cast to T* */ template<typename T> T *getPlugin(const std::string &name) { Loading Loading
src/authdb.cpp +28 −25 Original line number Diff line number Diff line Loading @@ -655,30 +655,7 @@ int main(int argc,char *argv[]){ key ); /* Drop privileges after binding HTTP socket */ #ifndef _WIN32 if (getuid() == 0) { struct passwd *pw = getpwnam("authdb"); if (pw) { if (setgid(pw->pw_gid) != 0) { std::cerr << "setgid failed" << std::endl; return 1; } if (initgroups("authdb", pw->pw_gid) != 0) { std::cerr << "initgroups failed" << std::endl; return 1; } if (setuid(pw->pw_uid) != 0) { std::cerr << "setuid failed" << std::endl; return 1; } } else { std::cerr << "user authdb not found, running as root" << std::endl; } } #endif /* Start cluster after priv drop so all files are owned by authdb */ /* Start cluster while still root so QUIC can bind privileged ports */ if (clusterEnabled) { cluster.init(ccfg); cluster.start(); Loading Loading @@ -764,7 +741,33 @@ int main(int argc,char *argv[]){ authdb::g_KdcPlugin = pluginMgr.getPlugin<authdb::KdcPlugin>("krb5"); authdb::g_AdPlugin = pluginMgr.getPlugin<authdb::AdPlugin>("ad"); /* Start each plugin in its own background thread */ /* Init plugins while still root — bind privileged ports (88, 389, etc.) */ pluginMgr.initAll(); /* Drop privileges after all sockets are bound */ #ifndef _WIN32 if (getuid() == 0) { struct passwd *pw = getpwnam("authdb"); if (pw) { if (setgid(pw->pw_gid) != 0) { std::cerr << "setgid failed" << std::endl; return 1; } if (initgroups("authdb", pw->pw_gid) != 0) { std::cerr << "initgroups failed" << std::endl; return 1; } if (setuid(pw->pw_uid) != 0) { std::cerr << "setuid failed" << std::endl; return 1; } } else { std::cerr << "user authdb not found, running as root" << std::endl; } } #endif /* Start each plugin in its own background thread (runs as unprivileged user) */ std::vector<std::thread> pluginThreads; for (auto &[pname, lp] : pluginMgr.plugins()) { pluginThreads.emplace_back([&lp, &pname](){ Loading
src/plugin.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -188,4 +188,17 @@ int PluginManager::loadAll(const std::string &directory, return loaded; } void PluginManager::initAll() { for (auto &[name, lp] : _Plugins) { if (lp.instance) { try { lp.instance->init(); } catch (const std::exception &e) { std::cerr << "Plugin init failed: " << name << ": " << e.what() << std::endl; } } } } } /* namespace authdb */
src/plugin.h +7 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,10 @@ namespace authdb { /* Human-readable name, e.g. "krb5", "ldap" */ virtual const char *name() const = 0; /* Bind sockets and acquire resources that require root. * Called before privilege drop. Default: no-op. */ virtual void init() {} /* Start the plugin (blocking – caller runs this in a thread) */ virtual void run() = 0; }; Loading Loading @@ -117,6 +121,9 @@ namespace authdb { AuthBackend &backend, const char *configJson = "{}"); /* Call init() on every loaded plugin (while still root) */ void initAll(); /* Retrieve a plugin by name, dynamically cast to T* */ template<typename T> T *getPlugin(const std::string &name) { Loading