- moved daemonize in its own file
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Mon, 8 Mar 2004 14:05:46 +0000 (14:05 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Mon, 8 Mar 2004 14:05:46 +0000 (14:05 +0000)
- removed suid stuff from daemonize and moved it in do_suid()
(ser will change uid now after opening the listening sockets)

daemonize.c [new file with mode: 0644]
daemonize.h [new file with mode: 0644]
globals.h
main.c

diff --git a/daemonize.c b/daemonize.c
new file mode 100644 (file)
index 0000000..8855fed
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2001-2003 Fhg Fokus
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    info@iptel.org
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * 
+ * History:
+ * --------
+ *  2004-02-20  removed from ser main.c into its own file (andrei)
+ *  2004-03-04  moved setuid/setgid in do_suid() (andrei)
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <syslog.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "daemonize.h"
+#include "globals.h"
+#include "dprint.h"
+
+
+#define MAX_FD 32 /* maximum number of inherited open file descriptors,
+                   (normally it shouldn't  be bigger  than 3) */
+
+
+
+/* daemon init, return 0 on success, -1 on error */
+int daemonize(char*  name)
+{
+       FILE *pid_stream;
+       pid_t pid;
+       int r, p;
+
+
+       p=-1;
+
+
+       if (chroot_dir&&(chroot(chroot_dir)<0)){
+               LOG(L_CRIT, "Cannot chroot to %s: %s\n", chroot_dir, strerror(errno));
+               goto error;
+       }
+       
+       if (chdir(working_dir)<0){
+               LOG(L_CRIT,"cannot chdir to %s: %s\n", working_dir, strerror(errno));
+               goto error;
+       }
+
+       /* fork to become!= group leader*/
+       if ((pid=fork())<0){
+               LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno));
+               goto error;
+       }else if (pid!=0){
+               /* parent process => exit*/
+               exit(0);
+       }
+       /* become session leader to drop the ctrl. terminal */
+       if (setsid()<0){
+               LOG(L_WARN, "setsid failed: %s\n",strerror(errno));
+       }else{
+               own_pgid=1;/* we have our own process group */
+       }
+       /* fork again to drop group  leadership */
+       if ((pid=fork())<0){
+               LOG(L_CRIT, "Cannot  fork:%s\n", strerror(errno));
+               goto error;
+       }else if (pid!=0){
+               /*parent process => exit */
+               exit(0);
+       }
+
+       /* added by noh: create a pid file for the main process */
+       if (pid_file!=0){
+               
+               if ((pid_stream=fopen(pid_file, "r"))!=NULL){
+                       fscanf(pid_stream, "%d", &p);
+                       fclose(pid_stream);
+                       if (p==-1){
+                               LOG(L_CRIT, "pid file %s exists, but doesn't contain a valid"
+                                       " pid number\n", pid_file);
+                               goto error;
+                       }
+                       if (kill((pid_t)p, 0)==0 || errno==EPERM){
+                               LOG(L_CRIT, "running process found in the pid file %s\n",
+                                       pid_file);
+                               goto error;
+                       }else{
+                               LOG(L_WARN, "pid file contains old pid, replacing pid\n");
+                       }
+               }
+               pid=getpid();
+               if ((pid_stream=fopen(pid_file, "w"))==NULL){
+                       LOG(L_WARN, "unable to create pid file %s: %s\n", 
+                               pid_file, strerror(errno));
+                       goto error;
+               }else{
+                       fprintf(pid_stream, "%i\n", (int)pid);
+                       fclose(pid_stream);
+               }
+       }
+       
+       /* try to replace stdin, stdout & stderr with /dev/null */
+       if (freopen("/dev/null", "r", stdin)==0){
+               LOG(L_ERR, "unable to replace stdin with /dev/null: %s\n",
+                               strerror(errno));
+               /* continue, leave it open */
+       };
+       if (freopen("/dev/null", "w", stdout)==0){
+               LOG(L_ERR, "unable to replace stdout with /dev/null: %s\n",
+                               strerror(errno));
+               /* continue, leave it open */
+       };
+       /* close stderr only if log_stderr=0 */
+       if ((!log_stderr) &&(freopen("/dev/null", "w", stderr)==0)){
+               LOG(L_ERR, "unable to replace stderr with /dev/null: %s\n",
+                               strerror(errno));
+               /* continue, leave it open */
+       };
+       
+       /* close any open file descriptors */
+       closelog();
+       for (r=3;r<MAX_FD; r++){
+                       close(r);
+       }
+       
+       if (log_stderr==0)
+               openlog(name, LOG_PID|LOG_CONS, log_facility);
+               /* LOG_CONS, LOG_PERRROR ? */
+
+       return  0;
+
+error:
+       return -1;
+}
+
+
+
+int do_suid()
+{
+       if (gid&&(setgid(gid)<0)){
+               LOG(L_CRIT, "cannot change gid to %d: %s\n", gid, strerror(errno));
+               goto error;
+       }
+       
+       if(uid&&(setuid(uid)<0)){
+               LOG(L_CRIT, "cannot change uid to %d: %s\n", uid, strerror(errno));
+               goto error;
+       }
+       return 0;
+error:
+       return -1;
+}
+
+
diff --git a/daemonize.h b/daemonize.h
new file mode 100644 (file)
index 0000000..f66b608
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2001-2003 Fhg Fokus
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    info@iptel.org
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * 
+ * History:
+ * --------
+ *  2004-02-20  created by andrei
+ */
+
+#ifndef _daemonize_h
+#define _daemonize_h
+
+int daemonize(char* name);
+int do_suid();
+
+
+#endif
index 9b281ea..028af20 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -48,6 +48,12 @@ extern int config_check;
 extern char *stat_file;
 extern unsigned short port_no;
 
+extern int uid;
+extern int gid;
+char* pid_file;
+extern int own_pgid; /* whether or not we have our own pgid (and it's ok
+>--->--->--->--->--->--->--->--->--->--->--- to use kill(0, sig) */
+
 extern struct socket_info* bind_address; /* pointer to the crt. proc.
                                                                                        listening address */
 extern struct socket_info* sendipv4; /* ipv4 socket to use when msg.
diff --git a/main.c b/main.c
index 2b757f8..024a5f6 100644 (file)
--- a/main.c
+++ b/main.c
@@ -79,6 +79,7 @@
 
 #include "config.h"
 #include "dprint.h"
+#include "daemonize.h"
 #include "route.h"
 #include "udp_server.h"
 #include "globals.h"
@@ -430,125 +431,6 @@ void cleanup(show_status)
 
 
 
-/* daemon init, return 0 on success, -1 on error */
-int daemonize(char*  name)
-{
-       FILE *pid_stream;
-       pid_t pid;
-       int r, p;
-
-
-       p=-1;
-
-
-       if (chroot_dir&&(chroot(chroot_dir)<0)){
-               LOG(L_CRIT, "Cannot chroot to %s: %s\n", chroot_dir, strerror(errno));
-               goto error;
-       }
-       
-       if (chdir(working_dir)<0){
-               LOG(L_CRIT,"cannot chdir to %s: %s\n", working_dir, strerror(errno));
-               goto error;
-       }
-
-       if (gid&&(setgid(gid)<0)){
-               LOG(L_CRIT, "cannot change gid to %d: %s\n", gid, strerror(errno));
-               goto error;
-       }
-       
-       if(uid&&(setuid(uid)<0)){
-               LOG(L_CRIT, "cannot change uid to %d: %s\n", uid, strerror(errno));
-               goto error;
-       }
-
-       /* fork to become!= group leader*/
-       if ((pid=fork())<0){
-               LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno));
-               goto error;
-       }else if (pid!=0){
-               /* parent process => exit*/
-               exit(0);
-       }
-       /* become session leader to drop the ctrl. terminal */
-       if (setsid()<0){
-               LOG(L_WARN, "setsid failed: %s\n",strerror(errno));
-       }else{
-               own_pgid=1; /* we have our own process group */
-       }
-       /* fork again to drop group  leadership */
-       if ((pid=fork())<0){
-               LOG(L_CRIT, "Cannot  fork:%s\n", strerror(errno));
-               goto error;
-       }else if (pid!=0){
-               /*parent process => exit */
-               exit(0);
-       }
-
-       /* added by noh: create a pid file for the main process */
-       if (pid_file!=0){
-               
-               if ((pid_stream=fopen(pid_file, "r"))!=NULL){
-                       fscanf(pid_stream, "%d", &p);
-                       fclose(pid_stream);
-                       if (p==-1){
-                               LOG(L_CRIT, "pid file %s exists, but doesn't contain a valid"
-                                       " pid number\n", pid_file);
-                               goto error;
-                       }
-                       if (kill((pid_t)p, 0)==0 || errno==EPERM){
-                               LOG(L_CRIT, "running process found in the pid file %s\n",
-                                       pid_file);
-                               goto error;
-                       }else{
-                               LOG(L_WARN, "pid file contains old pid, replacing pid\n");
-                       }
-               }
-               pid=getpid();
-               if ((pid_stream=fopen(pid_file, "w"))==NULL){
-                       LOG(L_WARN, "unable to create pid file %s: %s\n", 
-                               pid_file, strerror(errno));
-                       goto error;
-               }else{
-                       fprintf(pid_stream, "%i\n", (int)pid);
-                       fclose(pid_stream);
-               }
-       }
-       
-       /* try to replace stdin, stdout & stderr with /dev/null */
-       if (freopen("/dev/null", "r", stdin)==0){
-               LOG(L_ERR, "unable to replace stdin with /dev/null: %s\n",
-                               strerror(errno));
-               /* continue, leave it open */
-       };
-       if (freopen("/dev/null", "w", stdout)==0){
-               LOG(L_ERR, "unable to replace stdout with /dev/null: %s\n",
-                               strerror(errno));
-               /* continue, leave it open */
-       };
-       /* close stderr only if log_stderr=0 */
-       if ((!log_stderr) &&(freopen("/dev/null", "w", stderr)==0)){
-               LOG(L_ERR, "unable to replace stderr with /dev/null: %s\n",
-                               strerror(errno));
-               /* continue, leave it open */
-       };
-       
-       /* close any open file descriptors */
-       closelog();
-       for (r=3;r<MAX_FD; r++){
-                       close(r);
-       }
-       
-       if (log_stderr==0)
-               openlog(name, LOG_PID|LOG_CONS, log_facility);
-               /* LOG_CONS, LOG_PERRROR ? */
-       return  0;
-
-error:
-       return -1;
-}
-
-
-
 /* tries to send a signal to all our processes
  * if daemonized  is ok to send the signal to all the process group,
  * however if not daemonized we might end up sending the signal also
@@ -788,7 +670,7 @@ int main_loop()
                        LOG(L_WARN, "WARNING: using only the first listen address"
                                                " (no fork)\n");
                }
-
+               if (do_suid()==-1) goto error; /* try to drop priviledges */
                /* process_no now initialized to zero -- increase from now on
                   as new processes are forked (while skipping 0 reserved for main 
                */
@@ -917,6 +799,7 @@ int main_loop()
 #endif /* USE_TCP */
                        /* all procs should have access to all the sockets (for sending)
                         * so we open all first*/
+               if (do_suid()==-1) goto error; /* try to drop priviledges */
                /* udp processes */
                for(si=udp_listen; si; si=si->next){
                        for(i=0;i<children_no;i++){