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)
55 pw_ = getpwnam(username.c_str());
57 AnytunError::throwErr() << "unknown user " << username;
60 gr_ = getgrnam(groupname.c_str());
62 gr_ = getgrgid(pw_->pw_gid);
65 AnytunError::throwErr() << "unknown group " << groupname;
68 void DaemonService::dropPrivs()
73 if(setgid(gr_->gr_gid))
74 AnytunError::throwErr() << "setgid('" << gr_->gr_name << "') failed: " << AnytunErrno(errno);
77 gr_list[0] = gr_->gr_gid;
78 if(setgroups (1, gr_list))
79 AnytunError::throwErr() << "setgroups(['" << gr_->gr_name << "']) failed: " << AnytunErrno(errno);
81 if(setuid(pw_->pw_uid))
82 AnytunError::throwErr() << "setuid('" << pw_->pw_name << "') failed: " << AnytunErrno(errno);
84 cLog.msg(Log::PRIO_NOTICE) << "dropped privileges to " << pw_->pw_name << ":" << gr_->gr_name;
87 void DaemonService::chroot(std::string const& chrootdir)
90 AnytunError::throwErr() << "this program has to be run as root in order to run in a chroot";
92 if(::chroot(chrootdir.c_str()))
93 AnytunError::throwErr() << "can't chroot to " << chrootdir;
95 cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
97 AnytunError::throwErr() << "can't change to /";
100 /// TODO: this outstandignly ugly please and i really can't stress the please fix it asap!!!!!!!
102 std::ofstream pidFile; // FIXXXME no global variable
104 void DaemonService::daemonize()
106 // std::ofstream pidFile;
107 if(gOpt.getPidFile() != "") {
108 pidFile.open(gOpt.getPidFile().c_str());
109 if(!pidFile.is_open())
110 AnytunError::throwErr() << "can't open pid file (" << gOpt.getPidFile() << "): " << AnytunErrno(errno);
117 AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting";
124 AnytunError::throwErr() << "daemonizing failed at setsid(): " << AnytunErrno(errno) << ", exitting";
128 AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting";
132 if ((chdir("/")) < 0)
133 AnytunError::throwErr() << "daemonizing failed at chdir(): " << AnytunErrno(errno) << ", exitting";
135 // std::cout << "running in background now..." << std::endl;
138 // for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
139 for (fd=0;fd<=2;fd++) // close all file descriptors
141 fd = open("/dev/null",O_RDWR); // stdin
143 cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdin";
145 if(dup(fd) == -1) // stdout
146 cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdout";
147 if(dup(fd) == -1) // stderr
148 cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stderr";
151 // FIXXXXME: write this pid to file (currently pid from posix/signhandler.hpp:77 is used)
153 // if(pidFile.is_open()) {
154 // pid_t pid = getpid();
162 bool DaemonService::isDaemonized()