]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - contrib/ntp/ntpsnmpd/netsnmp_daemonize.c
Fix multiple vulnerabilities in ntp. [SA-18:02.ntp]
[FreeBSD/releng/10.3.git] / contrib / ntp / ntpsnmpd / netsnmp_daemonize.c
1 /*
2  * system.c
3  */
4 /* Portions of this file are subject to the following copyright(s).  See
5  * the Net-SNMP's COPYING file for more details and other copyrights
6  * that may apply:
7  */
8 /***********************************************************
9         Copyright 1992 by Carnegie Mellon University
10
11                       All Rights Reserved
12
13 Permission to use, copy, modify, and distribute this software and its
14 documentation for any purpose and without fee is hereby granted,
15 provided that the above copyright notice appear in all copies and that
16 both that copyright notice and this permission notice appear in
17 supporting documentation, and that the name of CMU not be
18 used in advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
22 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
23 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
24 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
25 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27 SOFTWARE.
28 ******************************************************************/
29 /*
30  * Portions of this file are copyrighted by:
31  * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
32  * Use is subject to license terms specified in the COPYING file
33  * distributed with the Net-SNMP package.
34  */
35 /*
36  * System dependent routines go here
37  */
38 #include <net-snmp/net-snmp-config.h>
39 #undef PACKAGE_BUGREPORT
40 #undef PACKAGE_NAME
41 #undef PACKAGE_STRING
42 #undef PACKAGE_TARNAME
43 #undef PACKAGE_URL
44 #undef PACKAGE_VERSION
45 #include <config.h>
46
47 #ifdef NEED_NETSNMP_DAEMONIZE
48
49 #include <stdio.h>
50 #include <ctype.h>
51 #include <errno.h>
52
53 #if HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56 #if HAVE_STDLIB_H
57 #include <stdlib.h>
58 #endif
59
60 #if TIME_WITH_SYS_TIME
61 # ifdef WIN32
62 #  include <sys/timeb.h>
63 # else
64 #  include <sys/time.h>
65 # endif
66 # include <time.h>
67 #else
68 # if HAVE_SYS_TIME_H
69 #  include <sys/time.h>
70 # else
71 #  include <time.h>
72 # endif
73 #endif
74
75 #include <sys/types.h>
76
77 #if HAVE_NETINET_IN_H
78 #include <netinet/in.h>
79 #endif
80
81 #if HAVE_WINSOCK_H
82 #include <winsock.h>
83 #endif
84 #if HAVE_SYS_SOCKET_H
85 #include <sys/socket.h>
86 #endif
87 #if HAVE_NET_IF_H
88 #include <net/if.h>
89 #endif
90
91 #if HAVE_SYS_SOCKIO_H
92 #include <sys/sockio.h>
93 #endif
94
95 #if HAVE_SYS_IOCTL_H
96 #include <sys/ioctl.h>
97 #endif
98
99 #ifdef HAVE_NLIST_H
100 #include <nlist.h>
101 #endif
102
103 #if HAVE_SYS_FILE_H
104 #include <sys/file.h>
105 #endif
106
107 #if HAVE_KSTAT_H
108 #include <kstat.h>
109 #endif
110
111 #if HAVE_SYS_PARAM_H
112 #include <sys/param.h>
113 #endif
114 #if HAVE_SYS_SYSCTL_H
115 #include <sys/sysctl.h>
116 #endif
117
118 #if HAVE_STRING_H
119 #include <string.h>
120 #else
121 #include <strings.h>
122 #endif
123
124 #if HAVE_DMALLOC_H
125 #include <dmalloc.h>
126 #endif
127
128 #ifdef HAVE_SYS_STAT_H
129 #include <sys/stat.h>
130 #endif
131 #if HAVE_FCNTL_H
132 #include <fcntl.h>
133 #endif
134
135 #if defined(hpux10) || defined(hpux11)
136 #include <sys/pstat.h>
137 #endif
138
139 #if HAVE_SYS_UTSNAME_H
140 #include <sys/utsname.h>
141 #endif
142
143 #if HAVE_SYS_SYSTEMCFG_H
144 #include <sys/systemcfg.h>
145 #endif
146
147 #if HAVE_SYS_SYSTEMINFO_H
148 #include <sys/systeminfo.h>
149 #endif
150
151 #include <net-snmp/types.h>
152 #include <net-snmp/output_api.h>
153 #include <net-snmp/utilities.h>
154 #include <net-snmp/library/system.h>    /* for "internal" definitions */
155
156 #include <net-snmp/library/snmp_api.h>
157 #include <net-snmp/library/read_config.h> /* for get_temp_file_pattern() */
158
159 #ifndef IFF_LOOPBACK
160 #       define IFF_LOOPBACK 0
161 #endif
162
163 #ifdef  INADDR_LOOPBACK
164 # define LOOPBACK    INADDR_LOOPBACK
165 #else
166 # define LOOPBACK    0x7f000001
167 #endif
168
169 /**
170  * fork current process into the background.
171  *
172  * This function forks a process into the background, in order to
173  * become a daemon process. It does a few things along the way:
174  *
175  * - becoming a process/session group leader, and  forking a second time so
176  *   that process/session group leader can exit.
177  *
178  * - changing the working directory to /
179  *
180  * - closing stdin, stdout and stderr (unless stderr_log is set) and
181  *   redirecting them to /dev/null
182  *
183  * @param quit_immediately : indicates if the parent process should
184  *                           exit after a successful fork.
185  * @param stderr_log       : indicates if stderr is being used for
186  *                           logging and shouldn't be closed
187  * @returns -1 : fork error
188  *           0 : child process returning
189  *          >0 : parent process returning. returned value is the child PID.
190  */
191 int
192 netsnmp_daemonize(int quit_immediately, int stderr_log)
193 {
194     int i = 0;
195     int saved_errno;
196
197     DEBUGMSGT(("daemonize","daemonizing...\n"));
198 #ifdef HAVE_WORKING_FORK
199     /*
200      * Fork to return control to the invoking process and to
201      * guarantee that we aren't a process group leader.
202      */
203     i = fork();
204     if (i != 0) {
205         /* Parent. */
206         saved_errno = errno;
207         DEBUGMSGT(("daemonize","first fork returned %d.\n", i));
208         if(i == -1) {
209             snmp_log(LOG_ERR,"first fork failed (errno %d) in "
210                      "netsnmp_daemonize()\n", saved_errno);
211             return -1;
212         }
213         if (quit_immediately) {
214             DEBUGMSGT(("daemonize","parent exiting\n"));
215             exit(0);
216         }
217     } else {
218         /* Child. */
219 #ifdef HAVE_SETSID
220         /* Become a process/session group leader. */
221         setsid();
222 #endif
223         /*
224          * Fork to let the process/session group leader exit.
225          */
226         if ((i = fork()) != 0) {
227             saved_errno = errno;
228             DEBUGMSGT(("daemonize","second fork returned %d.\n", i));
229             if(i == -1) {
230                 snmp_log(LOG_ERR,"second fork failed (errno %d) in "
231                          "netsnmp_daemonize()\n", saved_errno);
232             }
233             /* Parent. */
234             exit(0);
235         }
236 #ifndef WIN32
237         else {
238             /* Child. */
239             
240             DEBUGMSGT(("daemonize","child continuing\n"));
241
242             /* Avoid keeping any directory in use. */
243             chdir("/");
244             
245             if (!stderr_log) {
246                 /*
247                  * Close inherited file descriptors to avoid
248                  * keeping unnecessary references.
249                  */
250                 close(0);
251                 close(1);
252                 close(2);
253                 
254                 /*
255                  * Redirect std{in,out,err} to /dev/null, just in
256                  * case.
257                  */
258                 open("/dev/null", O_RDWR);
259                 dup(0);
260                 dup(0);
261             }
262         }
263 #endif /* !WIN32 */
264     }
265 #endif /* HAVE_WORKING_FORK */
266     return i;
267 }
268
269 #else /* !NEED_NETSNMP_DAEMONIZE */
270 int netsnp_daemonize_bs;
271 #endif