4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methodes used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, either version 3 of the License, or
24 * Anytun is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
41 #include "daemonService.h"
44 #include "anytunError.h"
46 DaemonService::DaemonService() : pw_(NULL), gr_(NULL), daemonized_(false)
50 void DaemonService::initPrivs(std::string const& username, std::string const& groupname)
56 pw_ = getpwnam(username.c_str());
58 AnytunError::throwErr() << "unknown user " << username;
62 gr_ = getgrnam(groupname.c_str());
64 gr_ = getgrgid(pw_->pw_gid);
68 AnytunError::throwErr() << "unknown group " << groupname;
72 void DaemonService::dropPrivs()
78 if(setgid(gr_->gr_gid)) {
79 AnytunError::throwErr() << "setgid('" << gr_->gr_name << "') failed: " << AnytunErrno(errno);
83 gr_list[0] = gr_->gr_gid;
84 if(setgroups(1, gr_list)) {
85 AnytunError::throwErr() << "setgroups(['" << gr_->gr_name << "']) failed: " << AnytunErrno(errno);
88 if(setuid(pw_->pw_uid)) {
89 AnytunError::throwErr() << "setuid('" << pw_->pw_name << "') failed: " << AnytunErrno(errno);
92 cLog.msg(Log::PRIO_NOTICE) << "dropped privileges to " << pw_->pw_name << ":" << gr_->gr_name;
95 void DaemonService::chroot(std::string const& chrootdir)
98 AnytunError::throwErr() << "this program has to be run as root in order to run in a chroot";
101 if(::chroot(chrootdir.c_str())) {
102 AnytunError::throwErr() << "can't chroot to " << chrootdir;
105 cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
107 AnytunError::throwErr() << "can't change to /";
111 /// TODO: this outstandignly ugly please and i really can't stress the please fix it asap!!!!!!!
113 std::ofstream pidFile; // FIXXXME no global variable
115 void DaemonService::daemonize()
117 // std::ofstream pidFile;
118 if(gOpt.getPidFile() != "") {
119 pidFile.open(gOpt.getPidFile().c_str());
120 if(!pidFile.is_open()) {
121 AnytunError::throwErr() << "can't open pid file (" << gOpt.getPidFile() << "): " << AnytunErrno(errno);
129 AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting";
137 AnytunError::throwErr() << "daemonizing failed at setsid(): " << AnytunErrno(errno) << ", exitting";
142 AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting";
147 if((chdir("/")) < 0) {
148 AnytunError::throwErr() << "daemonizing failed at chdir(): " << AnytunErrno(errno) << ", exitting";
151 // std::cout << "running in background now..." << std::endl;
154 // for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
155 for(fd=0; fd<=2; fd++) { // close all file descriptors
158 fd = open("/dev/null",O_RDWR); // stdin
160 cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdin";
162 if(dup(fd) == -1) { // stdout
163 cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdout";
165 if(dup(fd) == -1) { // stderr
166 cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stderr";
170 // FIXXXXME: write this pid to file (currently pid from posix/signhandler.hpp:77 is used)
172 // if(pidFile.is_open()) {
173 // pid_t pid = getpid();
181 bool DaemonService::isDaemonized()