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 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2001-2003 Fhg Fokus
5
+ *
6
+ * This file is part of ser, a free SIP server.
7
+ *
8
+ * ser is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * ser is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
27
+/*
28
+ * 
29
+ * History:
30
+ * --------
31
+ *  2004-02-20  removed from ser main.c into its own file (andrei)
32
+ *  2004-03-04  moved setuid/setgid in do_suid() (andrei)
33
+ */
34
+
35
+#include <sys/types.h>
36
+#include <unistd.h>
37
+#include <signal.h>
38
+#include <syslog.h>
39
+#include <errno.h>
40
+#include <string.h>
41
+#include <stdio.h>
42
+#include <stdlib.h>
43
+
44
+#include "daemonize.h"
45
+#include "globals.h"
46
+#include "dprint.h"
47
+
48
+
49
+#define MAX_FD 32 /* maximum number of inherited open file descriptors,
50
+		    (normally it shouldn't  be bigger  than 3) */
51
+
52
+
53
+
54
+/* daemon init, return 0 on success, -1 on error */
55
+int daemonize(char*  name)
56
+{
57
+	FILE *pid_stream;
58
+	pid_t pid;
59
+	int r, p;
60
+
61
+
62
+	p=-1;
63
+
64
+
65
+	if (chroot_dir&&(chroot(chroot_dir)<0)){
66
+		LOG(L_CRIT, "Cannot chroot to %s: %s\n", chroot_dir, strerror(errno));
67
+		goto error;
68
+	}
69
+	
70
+	if (chdir(working_dir)<0){
71
+		LOG(L_CRIT,"cannot chdir to %s: %s\n", working_dir, strerror(errno));
72
+		goto error;
73
+	}
74
+
75
+	/* fork to become!= group leader*/
76
+	if ((pid=fork())<0){
77
+		LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno));
78
+		goto error;
79
+	}else if (pid!=0){
80
+		/* parent process => exit*/
81
+		exit(0);
82
+	}
83
+	/* become session leader to drop the ctrl. terminal */
84
+	if (setsid()<0){
85
+		LOG(L_WARN, "setsid failed: %s\n",strerror(errno));
86
+	}else{
87
+		own_pgid=1;/* we have our own process group */
88
+	}
89
+	/* fork again to drop group  leadership */
90
+	if ((pid=fork())<0){
91
+		LOG(L_CRIT, "Cannot  fork:%s\n", strerror(errno));
92
+		goto error;
93
+	}else if (pid!=0){
94
+		/*parent process => exit */
95
+		exit(0);
96
+	}
97
+
98
+	/* added by noh: create a pid file for the main process */
99
+	if (pid_file!=0){
100
+		
101
+		if ((pid_stream=fopen(pid_file, "r"))!=NULL){
102
+			fscanf(pid_stream, "%d", &p);
103
+			fclose(pid_stream);
104
+			if (p==-1){
105
+				LOG(L_CRIT, "pid file %s exists, but doesn't contain a valid"
106
+					" pid number\n", pid_file);
107
+				goto error;
108
+			}
109
+			if (kill((pid_t)p, 0)==0 || errno==EPERM){
110
+				LOG(L_CRIT, "running process found in the pid file %s\n",
111
+					pid_file);
112
+				goto error;
113
+			}else{
114
+				LOG(L_WARN, "pid file contains old pid, replacing pid\n");
115
+			}
116
+		}
117
+		pid=getpid();
118
+		if ((pid_stream=fopen(pid_file, "w"))==NULL){
119
+			LOG(L_WARN, "unable to create pid file %s: %s\n", 
120
+				pid_file, strerror(errno));
121
+			goto error;
122
+		}else{
123
+			fprintf(pid_stream, "%i\n", (int)pid);
124
+			fclose(pid_stream);
125
+		}
126
+	}
127
+	
128
+	/* try to replace stdin, stdout & stderr with /dev/null */
129
+	if (freopen("/dev/null", "r", stdin)==0){
130
+		LOG(L_ERR, "unable to replace stdin with /dev/null: %s\n",
131
+				strerror(errno));
132
+		/* continue, leave it open */
133
+	};
134
+	if (freopen("/dev/null", "w", stdout)==0){
135
+		LOG(L_ERR, "unable to replace stdout with /dev/null: %s\n",
136
+				strerror(errno));
137
+		/* continue, leave it open */
138
+	};
139
+	/* close stderr only if log_stderr=0 */
140
+	if ((!log_stderr) &&(freopen("/dev/null", "w", stderr)==0)){
141
+		LOG(L_ERR, "unable to replace stderr with /dev/null: %s\n",
142
+				strerror(errno));
143
+		/* continue, leave it open */
144
+	};
145
+	
146
+	/* close any open file descriptors */
147
+	closelog();
148
+	for (r=3;r<MAX_FD; r++){
149
+			close(r);
150
+	}
151
+	
152
+	if (log_stderr==0)
153
+		openlog(name, LOG_PID|LOG_CONS, log_facility);
154
+		/* LOG_CONS, LOG_PERRROR ? */
155
+
156
+	return  0;
157
+
158
+error:
159
+	return -1;
160
+}
161
+
162
+
163
+
164
+int do_suid()
165
+{
166
+	if (gid&&(setgid(gid)<0)){
167
+		LOG(L_CRIT, "cannot change gid to %d: %s\n", gid, strerror(errno));
168
+		goto error;
169
+	}
170
+	
171
+	if(uid&&(setuid(uid)<0)){
172
+		LOG(L_CRIT, "cannot change uid to %d: %s\n", uid, strerror(errno));
173
+		goto error;
174
+	}
175
+	return 0;
176
+error:
177
+	return -1;
178
+}
179
+
180
+
0 181
new file mode 100644
... ...
@@ -0,0 +1,41 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2001-2003 Fhg Fokus
5
+ *
6
+ * This file is part of ser, a free SIP server.
7
+ *
8
+ * ser is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * ser is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
27
+/*
28
+ * 
29
+ * History:
30
+ * --------
31
+ *  2004-02-20  created by andrei
32
+ */
33
+
34
+#ifndef _daemonize_h
35
+#define _daemonize_h
36
+
37
+int daemonize(char* name);
38
+int do_suid();
39
+
40
+
41
+#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 431
 
431 432
 
432 433
 
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 434
 /* tries to send a signal to all our processes
553 435
  * if daemonized  is ok to send the signal to all the process group,
554 436
  * however if not daemonized we might end up sending the signal also
... ...
@@ -788,7 +670,7 @@ int main_loop()
788 670
 			LOG(L_WARN, "WARNING: using only the first listen address"
789 671
 						" (no fork)\n");
790 672
 		}
791
-
673
+		if (do_suid()==-1) goto error; /* try to drop priviledges */
792 674
 		/* process_no now initialized to zero -- increase from now on
793 675
 		   as new processes are forked (while skipping 0 reserved for main 
794 676
 		*/
... ...
@@ -917,6 +799,7 @@ int main_loop()
917 799
 #endif /* USE_TCP */
918 800
 			/* all procs should have access to all the sockets (for sending)
919 801
 			 * so we open all first*/
802
+		if (do_suid()==-1) goto error; /* try to drop priviledges */
920 803
 		/* udp processes */
921 804
 		for(si=udp_listen; si; si=si->next){
922 805
 			for(i=0;i<children_no;i++){