LTP GCOV extension - code coverage report
Current view: directory - trunk/src - miredo.c
Test: lcov.info
Date: 2007-05-09 Instrumented lines: 75
Code covered: 0.0 % Executed lines: 0

       1                 : /*
       2                 :  * miredo.c - Miredo common daemon functions
       3                 :  * $Id: miredo.c 1938 2007-02-22 20:55:28Z remi $
       4                 :  *
       5                 :  * See "Teredo: Tunneling IPv6 over UDP through NATs"
       6                 :  * for more information
       7                 :  */
       8                 : 
       9                 : /***********************************************************************
      10                 :  *  Copyright © 2004-2007 Rémi Denis-Courmont.                         *
      11                 :  *  This program is free software; you can redistribute and/or modify  *
      12                 :  *  it under the terms of the GNU General Public License as published  *
      13                 :  *  by the Free Software Foundation; version 2 of the license.         *
      14                 :  *                                                                     *
      15                 :  *  This program is distributed in the hope that it will be useful,    *
      16                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of     *
      17                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               *
      18                 :  *  See the GNU General Public License for more details.               *
      19                 :  *                                                                     *
      20                 :  *  You should have received a copy of the GNU General Public License  *
      21                 :  *  along with this program; if not, you can get it from:              *
      22                 :  *  http://www.gnu.org/copyleft/gpl.html                               *
      23                 :  ***********************************************************************/
      24                 : 
      25                 : #ifdef HAVE_CONFIG_H
      26                 : # include <config.h>
      27                 : #endif
      28                 : 
      29                 : #include <gettext.h>
      30                 : 
      31                 : #include <string.h> // memset(), strsignal()
      32                 : #include <stdlib.h> // exit()
      33                 : #include <inttypes.h>
      34                 : #include <stdbool.h>
      35                 : #include <stdarg.h>
      36                 : 
      37                 : #include <pthread.h> // pthread_sigmask()
      38                 : #include <signal.h> // sigaction()
      39                 : #include <errno.h>
      40                 : #include <sys/types.h>
      41                 : #include <sys/socket.h>
      42                 : #include <syslog.h>
      43                 : #include <unistd.h> // uid_t
      44                 : #include <sys/wait.h> // waitpid()
      45                 : #ifdef HAVE_SYS_CAPABILITY_H
      46                 : # include <sys/capability.h>
      47                 : #endif
      48                 : 
      49                 : #ifndef LOG_PERROR
      50                 : # define LOG_PERROR 0
      51                 : #endif
      52                 : 
      53                 : #include "miredo.h"
      54                 : #include "conf.h"
      55                 : 
      56                 : uid_t unpriv_uid = 0;
      57                 : const char *miredo_chrootdir = NULL;
      58                 : 
      59                 : extern int
      60                 : drop_privileges (void)
      61               0 : {
      62                 :         /*
      63                 :          * We could chroot earlier, but we do it know to keep compatibility with
      64                 :          * grsecurity Linux kernel patch that automatically removes capabilities
      65                 :          * when chrooted.
      66                 :          */
      67               0 :         if ((miredo_chrootdir != NULL)
      68                 :          && (chroot (miredo_chrootdir) || chdir ("/")))
      69                 :         {
      70               0 :                 syslog (LOG_ALERT, _("Error (%s): %s\n"),
      71                 :                                 "chroot", strerror (errno));
      72               0 :                 return -1;
      73                 :         }
      74                 : 
      75                 :         // Definitely drops privileges
      76               0 :         if (setuid (unpriv_uid))
      77                 :         {
      78               0 :                 syslog (LOG_ALERT, _("Error (%s): %s\n"), "setuid", strerror (errno));
      79               0 :                 return -1;
      80                 :         }
      81                 : 
      82                 : #ifdef HAVE_LIBCAP
      83               0 :         cap_t s = cap_init ();
      84               0 :         if (s != NULL)
      85                 :         {
      86               0 :                 cap_set_proc (s);
      87               0 :                 cap_free (s);
      88                 :         }
      89                 : #endif
      90               0 :         return 0;
      91                 : }
      92                 : 
      93                 : 
      94                 : /*
      95                 :  * Configuration and respawning stuff
      96                 :  */
      97                 : static void logger (void *dummy, bool error, const char *fmt, va_list ap)
      98               0 : {
      99                 :         (void)dummy;
     100                 : 
     101               0 :         vsyslog (error ? LOG_ERR : LOG_WARNING, fmt, ap);
     102               0 : }
     103                 : 
     104                 : 
     105                 : extern int
     106                 : miredo (const char *confpath, const char *server_name, int pidfd)
     107               0 : {
     108               0 :         int facility = LOG_DAEMON, retval;
     109               0 :         openlog (miredo_name, LOG_PID | LOG_PERROR, facility);
     110                 : 
     111               0 :         miredo_conf *cnf = miredo_conf_create (logger, NULL);
     112               0 :         if (cnf == NULL)
     113               0 :                 return -1;
     114                 : 
     115                 :         sigset_t set, oldset;
     116               0 :         sigemptyset (&set);
     117                 : 
     118               0 :         sigaddset (&set, SIGINT);
     119               0 :         sigaddset (&set, SIGQUIT);
     120               0 :         sigaddset (&set, SIGTERM);
     121               0 :         sigaddset (&set, SIGCHLD);
     122               0 :         sigset_t exit_set = set;
     123                 : 
     124               0 :         sigaddset (&set, SIGHUP);
     125               0 :         sigset_t reload_set = set;
     126                 : 
     127               0 :         sigaddset (&set, SIGPIPE);
     128                 : 
     129               0 :         pthread_sigmask (SIG_BLOCK, &set, &oldset);
     130                 : 
     131                 :         do
     132                 :         {
     133               0 :                 retval = 1;
     134                 : 
     135               0 :                 if (!miredo_conf_read_file (cnf, confpath))
     136                 :                 {
     137               0 :                         syslog (LOG_WARNING, _("Loading configuration from %s failed"),
     138                 :                                 confpath);
     139                 :                 }
     140                 : 
     141               0 :                 int newfac = LOG_DAEMON;
     142               0 :                 miredo_conf_parse_syslog_facility (cnf, "SyslogFacility", &newfac);
     143                 : 
     144                 :                 // Apply syslog facility change if needed
     145               0 :                 if (newfac != facility)
     146                 :                 {
     147               0 :                         closelog ();
     148               0 :                         facility = newfac;
     149               0 :                         openlog (miredo_name, LOG_PID, facility);
     150                 :                 }
     151               0 :                 syslog (LOG_INFO, _("Starting..."));
     152                 : 
     153                 :                 // Starts the main miredo process
     154               0 :                 pid_t pid = fork ();
     155                 : 
     156               0 :                 switch (pid)
     157                 :                 {
     158                 :                         case -1:
     159               0 :                                 syslog (LOG_ALERT, _("Error (%s): %s\n"), "fork",
     160                 :                                         strerror (errno));
     161               0 :                                 continue;
     162                 : 
     163                 :                         case 0:
     164               0 :                                 close (pidfd);
     165               0 :                                 retval = miredo_run (cnf, server_name);
     166               0 :                                 miredo_conf_destroy (cnf);
     167               0 :                                 closelog ();
     168               0 :                                 exit (-retval);
     169                 :                                 break;
     170                 : 
     171                 :                         default:
     172               0 :                                 miredo_conf_clear (cnf, 0);
     173                 :                 }
     174                 : 
     175                 :                 // Waits until the miredo process terminates
     176               0 :                 int val = 0, status;
     177               0 :                 while (sigwait (&set, &val) || !sigismember (&reload_set, val));
     178                 : 
     179               0 :                 if (sigismember (&exit_set, val))
     180                 :                 {
     181               0 :                         syslog (LOG_NOTICE, _("Exiting on signal %d (%s)"),
     182                 :                                 val, strsignal (val));
     183               0 :                         retval = 0;
     184                 :                 }
     185                 :                 else
     186                 :                 {
     187               0 :                         syslog (LOG_NOTICE,
     188                 :                                 _("Reloading configuration on signal %d (%s)"),
     189                 :                                 val, strsignal (val));
     190               0 :                         retval = 2;
     191                 :                 }
     192                 : 
     193                 :                 /* Terminate children (if not already done) */
     194               0 :                 if (val != SIGCHLD)
     195               0 :                         kill (pid, SIGTERM);
     196               0 :                 while (waitpid (pid, &status, 0) == -1);
     197                 : 
     198               0 :                 if (WIFEXITED (status))
     199                 :                 {
     200               0 :                         val = WEXITSTATUS (status);
     201               0 :                         syslog (LOG_NOTICE, _("Terminated (exit code: %d)"), val);
     202               0 :                         if (val)
     203               0 :                                 retval = 1;
     204                 :                 }
     205                 :                 else
     206               0 :                 if (WIFSIGNALED (status))
     207                 :                 {
     208               0 :                         val = WTERMSIG (status);
     209               0 :                         syslog (LOG_INFO, _("Child %d killed by signal %d (%s)"),
     210                 :                                 (int)pid, val, strsignal (val));
     211               0 :                         retval = 2;
     212                 :                         /* TODO: exponential restart delay */
     213                 :                 }
     214                 :         }
     215               0 :         while (retval == 2);
     216                 : 
     217               0 :         miredo_conf_destroy (cnf);
     218                 : 
     219               0 :         syslog (LOG_INFO, gettext (retval
     220                 :                 ? N_("Terminated with error(s).")
     221                 :                 : N_("Terminated with no error.")));
     222                 : 
     223               0 :         closelog ();
     224               0 :         return -retval;
     225                 : }
     226                 : 
     227                 : 
     228                 : int (*miredo_diagnose) (void);
     229                 : int (*miredo_run) (miredo_conf *conf, const char *server);
     230                 : 
     231                 : const char *miredo_name;
     232                 : 
     233                 : # ifdef HAVE_LIBCAP
     234                 : const cap_value_t *miredo_capv;
     235                 : int miredo_capc;
     236                 : # endif
     237                 : 

Generated by: LTP GCOV extension version 1.5