summaryrefslogtreecommitdiff
path: root/src/daemon.hpp
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2009-01-30 18:26:31 +0000
committerChristian Pointner <equinox@anytun.org>2009-01-30 18:26:31 +0000
commite8174227dec7cb107600a227647fa1abedcb5e63 (patch)
tree8194d03d8acbae15970a86f5198d736b62f82663 /src/daemon.hpp
parentsmall makefile cleanup (diff)
droping privileges is now possible without chroot
added groupname command line option
Diffstat (limited to 'src/daemon.hpp')
-rw-r--r--src/daemon.hpp89
1 files changed, 64 insertions, 25 deletions
diff --git a/src/daemon.hpp b/src/daemon.hpp
index 0bcd7f3..cc95337 100644
--- a/src/daemon.hpp
+++ b/src/daemon.hpp
@@ -33,6 +33,8 @@
#define _DAEMON_HPP
#ifndef NO_DAEMON
+#include <sstream>
+
#include <poll.h>
#include <fcntl.h>
#include <pwd.h>
@@ -41,39 +43,76 @@
#include <sys/stat.h>
#include <unistd.h>
-void chrootAndDrop(std::string const& chrootdir, std::string const& username)
+#include "log.h"
+
+class PrivInfo
{
- if (getuid() != 0)
+public:
+ PrivInfo(std::string const& username, std::string const& groupname)
{
- std::cerr << "this programm has to be run as root in order to run in a chroot" << std::endl;
- exit(-1);
+ pw_ = NULL;
+ gr_ = NULL;
+
+ if(username == "")
+ return;
+
+ pw_ = getpwnam(username.c_str());
+ if(!pw_)
+ throw std::runtime_error("unkown user " + username);
+
+ if(groupname != "")
+ gr_ = getgrnam(groupname.c_str());
+ else
+ gr_ = getgrgid(pw_->pw_gid);
+
+ if(!gr_)
+ throw std::runtime_error("unkown group " + groupname);
}
- struct passwd *pw = getpwnam(username.c_str());
- if(pw) {
- if(chroot(chrootdir.c_str()))
- {
- std::cerr << "can't chroot to " << chrootdir << std::endl;
- exit(-1);
+ void drop()
+ {
+ if(!pw_ || !gr_)
+ return;
+
+ if(setgid(gr_->gr_gid)) {
+ std::stringstream msg;
+ msg << "setgid('" << gr_->gr_name << "') failed: " << LogErrno(errno);
+ throw std::runtime_error(msg.str());
}
- cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
- if(chdir("/"))
- {
- std::cerr << "can't change to /" << std::endl;
- exit(-1);
+
+ gid_t gr_list[1];
+ gr_list[0] = gr_->gr_gid;
+ if(setgroups (1, gr_list)) {
+ std::stringstream msg;
+ msg << "setgroups(['" << gr_->gr_name << "']) failed: " << LogErrno(errno);
+ throw std::runtime_error(msg.str());
}
- if (initgroups(pw->pw_name, pw->pw_gid) || setgid(pw->pw_gid) || setuid(pw->pw_uid))
- {
- std::cerr << "can't drop to user " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
- exit(-1);
+
+ if(setuid(pw_->pw_uid)) {
+ std::stringstream msg;
+ msg << "setuid('" << pw_->pw_name << "') failed: " << LogErrno(errno);
+ throw std::runtime_error(msg.str());
}
- cLog.msg(Log::PRIO_NOTICE) << "dropped user to " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
- }
- else
- {
- std::cerr << "unknown user " << username << std::endl;
- exit(-1);
+
+ cLog.msg(Log::PRIO_NOTICE) << "dropped privileges to " << pw_->pw_name << ":" << gr_->gr_name;
}
+
+private:
+ struct passwd* pw_;
+ struct group* gr_;
+};
+
+void do_chroot(std::string const& chrootdir)
+{
+ if (getuid() != 0)
+ throw std::runtime_error("this programm has to be run as root in order to run in a chroot");
+
+ if(chroot(chrootdir.c_str()))
+ throw std::runtime_error("can't chroot to " + chrootdir);
+
+ cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
+ if(chdir("/"))
+ throw std::runtime_error("can't change to /");
}
void daemonize()