Apply patch based on the one from Cyril Brulebois for anytun to fix FTBFS on GNU...
[debian/uanytun.git] / src / daemon.h
1 /*
2  *  uAnytun
3  *
4  *  uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
5  *  featured implementation uAnytun has no support for multiple connections
6  *  or synchronisation. It is a small single threaded implementation intended
7  *  to act as a client on small platforms.
8  *  The secure anycast tunneling protocol (satp) defines a protocol used
9  *  for communication between any combination of unicast and anycast
10  *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
11  *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
12  *  ethernet, ip, arp ...). satp directly includes cryptography and
13  *  message authentication based on the methodes used by SRTP.  It is
14  *  intended to deliver a generic, scaleable and secure solution for
15  *  tunneling and relaying of packets of any protocol.
16  *  
17  *
18  *  Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org>
19  *
20  *  This file is part of uAnytun.
21  *
22  *  uAnytun is free software: you can redistribute it and/or modify
23  *  it under the terms of the GNU General Public License as published by
24  *  the Free Software Foundation, either version 3 of the License, or
25  *  any later version.
26  *
27  *  uAnytun is distributed in the hope that it will be useful,
28  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  *  GNU General Public License for more details.
31  *
32  *  You should have received a copy of the GNU General Public License
33  *  along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
34  */
35
36 #ifndef UANYTUN_daemon_h_INCLUDED
37 #define UANYTUN_daemon_h_INCLUDED
38
39 #include <poll.h>
40 #include <fcntl.h>
41 #include <pwd.h>
42 #include <grp.h>
43 #include <sys/wait.h>
44 #include <sys/stat.h>
45 #include <unistd.h>
46
47 struct priv_info_struct {
48   struct passwd* pw_;
49   struct group* gr_;
50 };
51 typedef struct priv_info_struct priv_info_t;
52
53 int priv_init(priv_info_t* priv, const char* username, const char* groupname)
54 {
55   if(!priv)
56     return -1;
57
58   priv->pw_ = NULL;
59   priv->gr_ = NULL;
60
61   priv->pw_ = getpwnam(username);
62   if(!priv->pw_) {
63     log_printf(ERROR, "unkown user %s", username);
64     return -1;
65   }
66
67   if(groupname)
68     priv->gr_ = getgrnam(groupname);
69   else
70     priv->gr_ = getgrgid(priv->pw_->pw_gid);
71
72   if(!priv->gr_) {
73     log_printf(ERROR, "unkown group %s", groupname);
74     return -1;
75   }
76
77   return 0;
78 }
79
80 int priv_drop(priv_info_t* priv)
81 {
82   if(!priv || !priv->pw_ || !priv->gr_) {
83     log_printf(ERROR, "privileges not initialized properly");
84     return -1;
85   }
86
87   if(setgid(priv->gr_->gr_gid))  {
88     log_printf(ERROR, "setgid('%s') failed: %s", priv->gr_->gr_name, strerror(errno));
89     return -1;
90   }
91
92   gid_t gr_list[1];
93   gr_list[0] = priv->gr_->gr_gid;
94   if(setgroups (1, gr_list)) {
95     log_printf(ERROR, "setgroups(['%s']) failed: %s", priv->gr_->gr_name, strerror(errno));
96     return -1;
97   }
98
99   if(setuid(priv->pw_->pw_uid)) {
100     log_printf(ERROR, "setuid('%s') failed: %s", priv->pw_->pw_name, strerror(errno));
101     return -1;
102   }
103
104   log_printf(NOTICE, "dropped privileges to %s:%s", priv->pw_->pw_name, priv->gr_->gr_name);
105   return 0;
106 }
107
108
109 int do_chroot(const char* chrootdir)
110 {
111   if(getuid() != 0) {
112     log_printf(ERROR, "this programm has to be run as root in order to run in a chroot");
113     return -1;
114   }
115
116   if(chroot(chrootdir)) {
117     log_printf(ERROR, "can't chroot to %s: %s", chrootdir, strerror(errno));
118     return -1;
119   }
120   log_printf(NOTICE, "we are in chroot jail (%s) now", chrootdir);
121   if(chdir("/")) {
122     log_printf(ERROR, "can't change to /: %s", strerror(errno));
123     return -1;
124   }
125 }
126
127 void daemonize()
128 {
129   pid_t pid;
130
131   pid = fork();
132   if(pid < 0) {
133     log_printf(ERROR, "daemonizing failed at fork(): %s, exitting", strerror(errno));
134     exit(-1);
135   }
136   if(pid) exit(0);
137
138   umask(0);
139
140   if(setsid() < 0) {
141     log_printf(ERROR, "daemonizing failed at setsid(): %s, exitting", strerror(errno));
142     exit(-1);
143   }
144
145   pid = fork();
146   if(pid < 0) {
147     log_printf(ERROR, "daemonizing failed at fork(): %s, exitting", strerror(errno));
148     exit(-1);
149   }
150   if(pid) exit(0);
151
152   if ((chdir("/")) < 0) {
153     log_printf(ERROR, "daemonizing failed at chdir(): %s, exitting", strerror(errno));
154     exit(-1);
155   }
156
157   int fd;
158   for (fd=0;fd<=2;fd++) // close all file descriptors
159     close(fd);
160   fd = open("/dev/null",O_RDWR);        // stdin
161   if(fd == -1)
162     log_printf(WARNING, "can't open stdin (chroot and no link to /dev/null?)");
163   else {
164     if(dup(fd) == -1)   // stdout
165       log_printf(WARNING, "can't open stdout");
166     if(dup(fd) == -1)   // stderr
167       log_printf(WARNING, "can't open stderr");
168   }
169   umask(027);
170 }
171
172 #endif
173