Browse code

- moved daemonize in its own file - removed suid stuff from daemonize and moved it in do_suid() (ser will change uid now after opening the listening sockets)

Andrei Pelinescu-Onciul authored on 08/03/2004 14:05:46
Showing 4 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,180 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2001-2003 Fhg Fokus
4
+ *
5
+ * This file is part of ser, a free SIP server.
6
+ *
7
+ * ser is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * For a license to use the ser software under conditions
13
+ * other than those described here, or to purchase support for this
14
+ * software, please contact iptel.org by e-mail at the following addresses:
15
+ *    info@iptel.org
16
+ *
17
+ * ser is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License 
23
+ * along with this program; if not, write to the Free Software 
24
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ */
26
+/*
27
+ * 
28
+ * History:
29
+ * --------
30
+ *  2004-02-20  removed from ser main.c into its own file (andrei)
31
+ *  2004-03-04  moved setuid/setgid in do_suid() (andrei)
32
+ */
33
+
34
+#include <sys/types.h>
35
+#include <unistd.h>
36
+#include <signal.h>
37
+#include <syslog.h>
38
+#include <errno.h>
39
+#include <string.h>
40
+#include <stdio.h>
41
+#include <stdlib.h>
42
+
43
+#include "daemonize.h"
44
+#include "globals.h"
45
+#include "dprint.h"
46
+
47
+
48
+#define MAX_FD 32 /* maximum number of inherited open file descriptors,
49
+		    (normally it shouldn't  be bigger  than 3) */
50
+
51
+
52
+
53
+/* daemon init, return 0 on success, -1 on error */
54
+int daemonize(char*  name)
55
+{
56
+	FILE *pid_stream;
57
+	pid_t pid;
58
+	int r, p;
59
+
60
+
61
+	p=-1;
62
+
63
+
64
+	if (chroot_dir&&(chroot(chroot_dir)<0)){
65
+		LOG(L_CRIT, "Cannot chroot to %s: %s\n", chroot_dir, strerror(errno));
66
+		goto error;
67
+	}
68
+	
69
+	if (chdir(working_dir)<0){
70
+		LOG(L_CRIT,"cannot chdir to %s: %s\n", working_dir, strerror(errno));
71
+		goto error;
72
+	}
73
+
74
+	/* fork to become!= group leader*/
75
+	if ((pid=fork())<0){
76
+		LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno));
77
+		goto error;
78
+	}else if (pid!=0){
79
+		/* parent process => exit*/
80
+		exit(0);
81
+	}
82
+	/* become session leader to drop the ctrl. terminal */
83
+	if (setsid()<0){
84
+		LOG(L_WARN, "setsid failed: %s\n",strerror(errno));
85
+	}else{
86
+		own_pgid=1;/* we have our own process group */
87
+	}
88
+	/* fork again to drop group  leadership */
89
+	if ((pid=fork())<0){
90
+		LOG(L_CRIT, "Cannot  fork:%s\n", strerror(errno));
91
+		goto error;
92
+	}else if (pid!=0){
93
+		/*parent process => exit */
94
+		exit(0);
95
+	}
96
+
97
+	/* added by noh: create a pid file for the main process */
98
+	if (pid_file!=0){
99
+		
100
+		if ((pid_stream=fopen(pid_file, "r"))!=NULL){
101
+			fscanf(pid_stream, "%d", &p);
102
+			fclose(pid_stream);
103
+			if (p==-1){
104
+				LOG(L_CRIT, "pid file %s exists, but doesn't contain a valid"
105
+					" pid number\n", pid_file);
106
+				goto error;
107
+			}
108
+			if (kill((pid_t)p, 0)==0 || errno==EPERM){
109
+				LOG(L_CRIT, "running process found in the pid file %s\n",
110
+					pid_file);
111
+				goto error;
112
+			}else{
113
+				LOG(L_WARN, "pid file contains old pid, replacing pid\n");
114
+			}
115
+		}
116
+		pid=getpid();
117
+		if ((pid_stream=fopen(pid_file, "w"))==NULL){
118
+			LOG(L_WARN, "unable to create pid file %s: %s\n", 
119
+				pid_file, strerror(errno));
120
+			goto error;
121
+		}else{
122
+			fprintf(pid_stream, "%i\n", (int)pid);
123
+			fclose(pid_stream);
124
+		}
125
+	}
126
+	
127
+	/* try to replace stdin, stdout & stderr with /dev/null */
128
+	if (freopen("/dev/null", "r", stdin)==0){
129
+		LOG(L_ERR, "unable to replace stdin with /dev/null: %s\n",
130
+				strerror(errno));
131
+		/* continue, leave it open */
132
+	};
133
+	if (freopen("/dev/null", "w", stdout)==0){
134
+		LOG(L_ERR, "unable to replace stdout with /dev/null: %s\n",
135
+				strerror(errno));
136
+		/* continue, leave it open */
137
+	};
138
+	/* close stderr only if log_stderr=0 */
139
+	if ((!log_stderr) &&(freopen("/dev/null", "w", stderr)==0)){
140
+		LOG(L_ERR, "unable to replace stderr with /dev/null: %s\n",
141
+				strerror(errno));
142
+		/* continue, leave it open */
143
+	};
144
+	
145
+	/* close any open file descriptors */
146
+	closelog();
147
+	for (r=3;r<MAX_FD; r++){
148
+			close(r);
149
+	}
150
+	
151
+	if (log_stderr==0)
152
+		openlog(name, LOG_PID|LOG_CONS, log_facility);
153
+		/* LOG_CONS, LOG_PERRROR ? */
154
+
155
+	return  0;
156
+
157
+error:
158
+	return -1;
159
+}
160
+
161
+
162
+
163
+int do_suid()
164
+{
165
+	if (gid&&(setgid(gid)<0)){
166
+		LOG(L_CRIT, "cannot change gid to %d: %s\n", gid, strerror(errno));
167
+		goto error;
168
+	}
169
+	
170
+	if(uid&&(setuid(uid)<0)){
171
+		LOG(L_CRIT, "cannot change uid to %d: %s\n", uid, strerror(errno));
172
+		goto error;
173
+	}
174
+	return 0;
175
+error:
176
+	return -1;
177
+}
178
+
179
+
0 180
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2001-2003 Fhg Fokus
4
+ *
5
+ * This file is part of ser, a free SIP server.
6
+ *
7
+ * ser is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * For a license to use the ser software under conditions
13
+ * other than those described here, or to purchase support for this
14
+ * software, please contact iptel.org by e-mail at the following addresses:
15
+ *    info@iptel.org
16
+ *
17
+ * ser is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License 
23
+ * along with this program; if not, write to the Free Software 
24
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ */
26
+/*
27
+ * 
28
+ * History:
29
+ * --------
30
+ *  2004-02-20  created by andrei
31
+ */
32
+
33
+#ifndef _daemonize_h
34
+#define _daemonize_h
35
+
36
+int daemonize(char* name);
37
+int do_suid();
38
+
39
+
40
+#endif
... ...
@@ -48,6 +48,12 @@ extern int config_check;
48 48
 extern char *stat_file;
49 49
 extern unsigned short port_no;
50 50
 
51
+extern int uid;
52
+extern int gid;
53
+char* pid_file;
54
+extern int own_pgid; /* whether or not we have our own pgid (and it's ok
55
+>--->--->--->--->--->--->--->--->--->--->--- to use kill(0, sig) */
56
+
51 57
 extern struct socket_info* bind_address; /* pointer to the crt. proc.
52 58
 											listening address */
53 59
 extern struct socket_info* sendipv4; /* ipv4 socket to use when msg.
... ...
@@ -79,6 +79,7 @@
79 79
 
80 80
 #include "config.h"
81 81
 #include "dprint.h"
82
+#include "daemonize.h"
82 83
 #include "route.h"
83 84
 #include "udp_server.h"
84 85
 #include "globals.h"
... ...
@@ -430,125 +431,6 @@ void cleanup(show_status)
430 430
 
431 431
 
432 432
 
433
-/* daemon init, return 0 on success, -1 on error */
434
-int daemonize(char*  name)
435
-{
436
-	FILE *pid_stream;
437
-	pid_t pid;
438
-	int r, p;
439
-
440
-
441
-	p=-1;
442
-
443
-
444
-	if (chroot_dir&&(chroot(chroot_dir)<0)){
445
-		LOG(L_CRIT, "Cannot chroot to %s: %s\n", chroot_dir, strerror(errno));
446
-		goto error;
447
-	}
448
-	
449
-	if (chdir(working_dir)<0){
450
-		LOG(L_CRIT,"cannot chdir to %s: %s\n", working_dir, strerror(errno));
451
-		goto error;
452
-	}
453
-
454
-	if (gid&&(setgid(gid)<0)){
455
-		LOG(L_CRIT, "cannot change gid to %d: %s\n", gid, strerror(errno));
456
-		goto error;
457
-	}
458
-	
459
-	if(uid&&(setuid(uid)<0)){
460
-		LOG(L_CRIT, "cannot change uid to %d: %s\n", uid, strerror(errno));
461
-		goto error;
462
-	}
463
-
464
-	/* fork to become!= group leader*/
465
-	if ((pid=fork())<0){
466
-		LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno));
467
-		goto error;
468
-	}else if (pid!=0){
469
-		/* parent process => exit*/
470
-		exit(0);
471
-	}
472
-	/* become session leader to drop the ctrl. terminal */
473
-	if (setsid()<0){
474
-		LOG(L_WARN, "setsid failed: %s\n",strerror(errno));
475
-	}else{
476
-		own_pgid=1; /* we have our own process group */
477
-	}
478
-	/* fork again to drop group  leadership */
479
-	if ((pid=fork())<0){
480
-		LOG(L_CRIT, "Cannot  fork:%s\n", strerror(errno));
481
-		goto error;
482
-	}else if (pid!=0){
483
-		/*parent process => exit */
484
-		exit(0);
485
-	}
486
-
487
-	/* added by noh: create a pid file for the main process */
488
-	if (pid_file!=0){
489
-		
490
-		if ((pid_stream=fopen(pid_file, "r"))!=NULL){
491
-			fscanf(pid_stream, "%d", &p);
492
-			fclose(pid_stream);
493
-			if (p==-1){
494
-				LOG(L_CRIT, "pid file %s exists, but doesn't contain a valid"
495
-					" pid number\n", pid_file);
496
-				goto error;
497
-			}
498
-			if (kill((pid_t)p, 0)==0 || errno==EPERM){
499
-				LOG(L_CRIT, "running process found in the pid file %s\n",
500
-					pid_file);
501
-				goto error;
502
-			}else{
503
-				LOG(L_WARN, "pid file contains old pid, replacing pid\n");
504
-			}
505
-		}
506
-		pid=getpid();
507
-		if ((pid_stream=fopen(pid_file, "w"))==NULL){
508
-			LOG(L_WARN, "unable to create pid file %s: %s\n", 
509
-				pid_file, strerror(errno));
510
-			goto error;
511
-		}else{
512
-			fprintf(pid_stream, "%i\n", (int)pid);
513
-			fclose(pid_stream);
514
-		}
515
-	}
516
-	
517
-	/* try to replace stdin, stdout & stderr with /dev/null */
518
-	if (freopen("/dev/null", "r", stdin)==0){
519
-		LOG(L_ERR, "unable to replace stdin with /dev/null: %s\n",
520
-				strerror(errno));
521
-		/* continue, leave it open */
522
-	};
523
-	if (freopen("/dev/null", "w", stdout)==0){
524
-		LOG(L_ERR, "unable to replace stdout with /dev/null: %s\n",
525
-				strerror(errno));
526
-		/* continue, leave it open */
527
-	};
528
-	/* close stderr only if log_stderr=0 */
529
-	if ((!log_stderr) &&(freopen("/dev/null", "w", stderr)==0)){
530
-		LOG(L_ERR, "unable to replace stderr with /dev/null: %s\n",
531
-				strerror(errno));
532
-		/* continue, leave it open */
533
-	};
534
-	
535
-	/* close any open file descriptors */
536
-	closelog();
537
-	for (r=3;r<MAX_FD; r++){
538
-			close(r);
539
-	}
540
-	
541
-	if (log_stderr==0)
542
-		openlog(name, LOG_PID|LOG_CONS, log_facility);
543
-		/* LOG_CONS, LOG_PERRROR ? */
544
-	return  0;
545
-
546
-error:
547
-	return -1;
548
-}
549
-
550
-
551
-
552 433
 /* tries to send a signal to all our processes
553 434
  * if daemonized  is ok to send the signal to all the process group,
554 435
  * however if not daemonized we might end up sending the signal also
... ...
@@ -788,7 +670,7 @@ int main_loop()
788 788
 			LOG(L_WARN, "WARNING: using only the first listen address"
789 789
 						" (no fork)\n");
790 790
 		}
791
-
791
+		if (do_suid()==-1) goto error; /* try to drop priviledges */
792 792
 		/* process_no now initialized to zero -- increase from now on
793 793
 		   as new processes are forked (while skipping 0 reserved for main 
794 794
 		*/
... ...
@@ -917,6 +799,7 @@ int main_loop()
917 917
 #endif /* USE_TCP */
918 918
 			/* all procs should have access to all the sockets (for sending)
919 919
 			 * so we open all first*/
920
+		if (do_suid()==-1) goto error; /* try to drop priviledges */
920 921
 		/* udp processes */
921 922
 		for(si=udp_listen; si; si=si->next){
922 923
 			for(i=0;i<children_no;i++){