Merge lp:~logan/ubuntu/raring/nagios-nrpe/2.13-1ubuntu1 into lp:ubuntu/raring/nagios-nrpe
- Raring (13.04)
- 2.13-1ubuntu1
- Merge into raring
Proposed by
Logan Rosen
Status: | Merged |
---|---|
Merged at revision: | 18 |
Proposed branch: | lp:~logan/ubuntu/raring/nagios-nrpe/2.13-1ubuntu1 |
Merge into: | lp:ubuntu/raring/nagios-nrpe |
Diff against target: |
10202 lines (+5245/-4745) 26 files modified
.cvsignore (+0/-1) Changelog (+7/-0) configure (+2/-2) configure.in (+2/-2) contrib/nrpe_check_control.c (+121/-121) debian/changelog (+18/-0) debian/compat (+1/-1) debian/control (+2/-2) debian/patches/01_nodevrandom-and-docoptions.dpatch (+34/-54) debian/patches/04_weird_output.dpatch (+13/-13) debian/patches/05_pid_privileges.dpatch (+20/-20) include/acl.h (+65/-0) include/common.h (+84/-71) include/dh.h (+6/-6) include/nrpe.h (+65/-61) include/utils.h (+62/-62) nrpe.spec (+1/-1) sample-config/nrpe.cfg.in (+3/-1) src/.cvsignore (+0/-1) src/Makefile.in (+2/-2) src/acl.c (+469/-0) src/check_nrpe.c (+462/-462) src/nrpe.c (+1912/-1968) src/snprintf.c (+1452/-1452) src/utils.c (+440/-440) update-version (+2/-2) |
To merge this branch: | bzr merge lp:~logan/ubuntu/raring/nagios-nrpe/2.13-1ubuntu1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Holbach (community) | Approve | ||
Ubuntu branches | Pending | ||
Review via email: mp+146287@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed file '.cvsignore' |
2 | --- .cvsignore 2011-10-18 15:09:21 +0000 |
3 | +++ .cvsignore 1970-01-01 00:00:00 +0000 |
4 | @@ -1,1 +0,0 @@ |
5 | -autom4te.cache |
6 | |
7 | === modified file 'Changelog' (properties changed: -x to +x) |
8 | --- Changelog 2008-08-06 20:33:57 +0000 |
9 | +++ Changelog 2013-02-02 23:23:20 +0000 |
10 | @@ -3,6 +3,13 @@ |
11 | ************** |
12 | |
13 | |
14 | +2.13 - 11/11/2011 |
15 | +----------------- |
16 | +- Applied Kaspersky Labs supplied patch for extending allowed_hosts (Konstantin Malov) |
17 | +- Fixed bug in allowed_hosts parsing (Eric Stanley) |
18 | +- Updated to support compiling on Solaris 10 (thanks to Kevin Pendleton) |
19 | + |
20 | + |
21 | 2.12 - 03/10/2008 |
22 | ----------------- |
23 | - Fix for unterminated multiline plugin (garbage) output (Krzysztof Oledzki) |
24 | |
25 | === modified file 'LEGAL' (properties changed: -x to +x) |
26 | === modified file 'Makefile.in' (properties changed: -x to +x) |
27 | === modified file 'README' (properties changed: -x to +x) |
28 | === modified file 'README.SSL' (properties changed: -x to +x) |
29 | === modified file 'SECURITY' (properties changed: -x to +x) |
30 | === added directory 'common' |
31 | === modified file 'configure' |
32 | --- configure 2008-08-06 20:33:57 +0000 |
33 | +++ configure 2013-02-02 23:23:20 +0000 |
34 | @@ -1298,9 +1298,9 @@ |
35 | |
36 | |
37 | PKG_NAME=nrpe |
38 | -PKG_VERSION="2.12" |
39 | +PKG_VERSION="2.13" |
40 | PKG_HOME_URL="http://www.nagios.org/" |
41 | -PKG_REL_DATE="03-10-2008" |
42 | +PKG_REL_DATE="11-11-2011" |
43 | |
44 | ac_aux_dir= |
45 | for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do |
46 | |
47 | === modified file 'configure.in' (properties changed: -x to +x) |
48 | --- configure.in 2008-08-06 20:33:57 +0000 |
49 | +++ configure.in 2013-02-02 23:23:20 +0000 |
50 | @@ -9,9 +9,9 @@ |
51 | AC_PREFIX_DEFAULT(/usr/local/nagios) |
52 | |
53 | PKG_NAME=nrpe |
54 | -PKG_VERSION="2.12" |
55 | +PKG_VERSION="2.13" |
56 | PKG_HOME_URL="http://www.nagios.org/" |
57 | -PKG_REL_DATE="03-10-2008" |
58 | +PKG_REL_DATE="11-11-2011" |
59 | |
60 | dnl Figure out how to invoke "install" and what install options to use. |
61 | AC_PROG_INSTALL |
62 | |
63 | === modified file 'contrib/README.nrpe_check_control' (properties changed: -x to +x) |
64 | === modified file 'contrib/nrpe_check_control.c' (properties changed: -x to +x) |
65 | --- contrib/nrpe_check_control.c 2004-05-15 12:02:35 +0000 |
66 | +++ contrib/nrpe_check_control.c 2013-02-02 23:23:20 +0000 |
67 | @@ -1,121 +1,121 @@ |
68 | -#include <stdio.h> |
69 | -#include <string.h> |
70 | -#include <time.h> |
71 | - |
72 | -#define MAX_CHARS 1024 |
73 | -#define SERVICE_COUNT 12 |
74 | - |
75 | -#define COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd" |
76 | -#define SERVICES_FILE "/usr/local/nagios/etc/services.cfg" |
77 | - |
78 | -int main(int argc, char *argv[]) |
79 | -{ |
80 | - char check_name[MAX_CHARS]; |
81 | - char ent_type[MAX_CHARS]; |
82 | - char input_buffer[MAX_CHARS]; |
83 | - char host_name[MAX_CHARS]; |
84 | - char service_name[MAX_CHARS]; |
85 | - char state[MAX_CHARS]; |
86 | - char state_type[MAX_CHARS]; |
87 | - char temp_input[MAX_CHARS]; |
88 | - char temp_string[MAX_CHARS]; |
89 | - char test_host[MAX_CHARS]; |
90 | - |
91 | - char *temp_var; |
92 | - |
93 | - FILE *command_fp; |
94 | - FILE *services_fp; |
95 | - |
96 | - int attempt; |
97 | - int i; |
98 | - |
99 | - time_t current_time; |
100 | - |
101 | - strcpy(state,argv[1]); |
102 | - strcpy(state_type,argv[2]); |
103 | - attempt=atoi(argv[3]); |
104 | - strcpy(host_name,argv[4]); |
105 | - |
106 | - if(strcmp(state,"OK") == 0) |
107 | - { |
108 | - services_fp=fopen(SERVICES_FILE,"r"); |
109 | - command_fp=fopen(COMMAND_FILE,"a"); |
110 | - while((fgets(input_buffer,MAX_CHARS-1,services_fp)) != NULL) |
111 | - { |
112 | - if(input_buffer[0]=='#' || input_buffer[0]=='\x0' || input_buffer[0]=='\n' || input_buffer[0]=='\r') |
113 | - { |
114 | - continue; |
115 | - } |
116 | - else |
117 | - { |
118 | - strcpy(temp_input,input_buffer); |
119 | - strcpy(temp_string,strtok(temp_input,"=")); |
120 | - strcpy(ent_type,strtok(temp_string,"[")); |
121 | - if(strcmp(ent_type,"service") == 0) |
122 | - { |
123 | - strcpy(test_host,strtok(NULL,"]")); |
124 | - if(strcmp(test_host,host_name) == 0) |
125 | - { |
126 | - temp_var=strtok(input_buffer,"="); |
127 | - strcpy(service_name,strtok(NULL,";")); |
128 | - for(i=1;i<=SERVICE_COUNT;i++) |
129 | - { |
130 | - temp_var=strtok(NULL,";"); |
131 | - } |
132 | - strcpy(check_name,strtok(temp_var,"!")); |
133 | - if(strcmp(check_name,"check_nrpe") == 0) |
134 | - { |
135 | - time(¤t_time); |
136 | - fprintf(command_fp,"[%lu] ENABLE_SVC_CHECK;%s;%s\n",current_time,host_name,service_name); |
137 | - } |
138 | - } |
139 | - } |
140 | - } |
141 | - } |
142 | - fclose(command_fp); |
143 | - fclose(services_fp); |
144 | - } |
145 | - else if(strcmp(state,"CRITICAL") == 0) |
146 | - { |
147 | - if(attempt == 3) |
148 | - { |
149 | - services_fp=fopen(SERVICES_FILE,"r"); |
150 | - command_fp=fopen(COMMAND_FILE,"a"); |
151 | - while((fgets(input_buffer,MAX_CHARS-1,services_fp)) != NULL) |
152 | - { |
153 | - if(input_buffer[0]=='#' || input_buffer[0]=='\x0' || input_buffer[0]=='\n' || input_buffer[0]=='\r') |
154 | - { |
155 | - continue; |
156 | - } |
157 | - else |
158 | - { |
159 | - strcpy(temp_input,input_buffer); |
160 | - strcpy(temp_string,strtok(temp_input,"=")); |
161 | - strcpy(ent_type,strtok(temp_string,"[")); |
162 | - if(strcmp(ent_type,"service") == 0) |
163 | - { |
164 | - strcpy(test_host,strtok(NULL,"]")); |
165 | - if(strcmp(test_host,host_name) == 0) |
166 | - { |
167 | - temp_var=strtok(input_buffer,"="); |
168 | - strcpy(service_name,strtok(NULL,";")); |
169 | - for(i=1;i<=SERVICE_COUNT;i++) |
170 | - { |
171 | - temp_var=strtok(NULL,";"); |
172 | - } |
173 | - strcpy(check_name,strtok(temp_var,"!")); |
174 | - if(strcmp(check_name,"check_nrpe") == 0) |
175 | - { |
176 | - time(¤t_time); |
177 | - fprintf(command_fp,"[%lu] DISABLE_SVC_CHECK;%s;%s\n",current_time,host_name,service_name); |
178 | - } |
179 | - } |
180 | - } |
181 | - } |
182 | - } |
183 | - fclose(command_fp); |
184 | - fclose(services_fp); |
185 | - } |
186 | - } |
187 | - return 0; |
188 | -} |
189 | +#include <stdio.h> |
190 | +#include <string.h> |
191 | +#include <time.h> |
192 | + |
193 | +#define MAX_CHARS 1024 |
194 | +#define SERVICE_COUNT 12 |
195 | + |
196 | +#define COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd" |
197 | +#define SERVICES_FILE "/usr/local/nagios/etc/services.cfg" |
198 | + |
199 | +int main(int argc, char *argv[]) |
200 | +{ |
201 | + char check_name[MAX_CHARS]; |
202 | + char ent_type[MAX_CHARS]; |
203 | + char input_buffer[MAX_CHARS]; |
204 | + char host_name[MAX_CHARS]; |
205 | + char service_name[MAX_CHARS]; |
206 | + char state[MAX_CHARS]; |
207 | + char state_type[MAX_CHARS]; |
208 | + char temp_input[MAX_CHARS]; |
209 | + char temp_string[MAX_CHARS]; |
210 | + char test_host[MAX_CHARS]; |
211 | + |
212 | + char *temp_var; |
213 | + |
214 | + FILE *command_fp; |
215 | + FILE *services_fp; |
216 | + |
217 | + int attempt; |
218 | + int i; |
219 | + |
220 | + time_t current_time; |
221 | + |
222 | + strcpy(state,argv[1]); |
223 | + strcpy(state_type,argv[2]); |
224 | + attempt=atoi(argv[3]); |
225 | + strcpy(host_name,argv[4]); |
226 | + |
227 | + if(strcmp(state,"OK") == 0) |
228 | + { |
229 | + services_fp=fopen(SERVICES_FILE,"r"); |
230 | + command_fp=fopen(COMMAND_FILE,"a"); |
231 | + while((fgets(input_buffer,MAX_CHARS-1,services_fp)) != NULL) |
232 | + { |
233 | + if(input_buffer[0]=='#' || input_buffer[0]=='\x0' || input_buffer[0]=='\n' || input_buffer[0]=='\r') |
234 | + { |
235 | + continue; |
236 | + } |
237 | + else |
238 | + { |
239 | + strcpy(temp_input,input_buffer); |
240 | + strcpy(temp_string,strtok(temp_input,"=")); |
241 | + strcpy(ent_type,strtok(temp_string,"[")); |
242 | + if(strcmp(ent_type,"service") == 0) |
243 | + { |
244 | + strcpy(test_host,strtok(NULL,"]")); |
245 | + if(strcmp(test_host,host_name) == 0) |
246 | + { |
247 | + temp_var=strtok(input_buffer,"="); |
248 | + strcpy(service_name,strtok(NULL,";")); |
249 | + for(i=1;i<=SERVICE_COUNT;i++) |
250 | + { |
251 | + temp_var=strtok(NULL,";"); |
252 | + } |
253 | + strcpy(check_name,strtok(temp_var,"!")); |
254 | + if(strcmp(check_name,"check_nrpe") == 0) |
255 | + { |
256 | + time(¤t_time); |
257 | + fprintf(command_fp,"[%lu] ENABLE_SVC_CHECK;%s;%s\n",current_time,host_name,service_name); |
258 | + } |
259 | + } |
260 | + } |
261 | + } |
262 | + } |
263 | + fclose(command_fp); |
264 | + fclose(services_fp); |
265 | + } |
266 | + else if(strcmp(state,"CRITICAL") == 0) |
267 | + { |
268 | + if(attempt == 3) |
269 | + { |
270 | + services_fp=fopen(SERVICES_FILE,"r"); |
271 | + command_fp=fopen(COMMAND_FILE,"a"); |
272 | + while((fgets(input_buffer,MAX_CHARS-1,services_fp)) != NULL) |
273 | + { |
274 | + if(input_buffer[0]=='#' || input_buffer[0]=='\x0' || input_buffer[0]=='\n' || input_buffer[0]=='\r') |
275 | + { |
276 | + continue; |
277 | + } |
278 | + else |
279 | + { |
280 | + strcpy(temp_input,input_buffer); |
281 | + strcpy(temp_string,strtok(temp_input,"=")); |
282 | + strcpy(ent_type,strtok(temp_string,"[")); |
283 | + if(strcmp(ent_type,"service") == 0) |
284 | + { |
285 | + strcpy(test_host,strtok(NULL,"]")); |
286 | + if(strcmp(test_host,host_name) == 0) |
287 | + { |
288 | + temp_var=strtok(input_buffer,"="); |
289 | + strcpy(service_name,strtok(NULL,";")); |
290 | + for(i=1;i<=SERVICE_COUNT;i++) |
291 | + { |
292 | + temp_var=strtok(NULL,";"); |
293 | + } |
294 | + strcpy(check_name,strtok(temp_var,"!")); |
295 | + if(strcmp(check_name,"check_nrpe") == 0) |
296 | + { |
297 | + time(¤t_time); |
298 | + fprintf(command_fp,"[%lu] DISABLE_SVC_CHECK;%s;%s\n",current_time,host_name,service_name); |
299 | + } |
300 | + } |
301 | + } |
302 | + } |
303 | + } |
304 | + fclose(command_fp); |
305 | + fclose(services_fp); |
306 | + } |
307 | + } |
308 | + return 0; |
309 | +} |
310 | |
311 | === modified file 'debian/changelog' |
312 | --- debian/changelog 2012-05-16 17:29:52 +0000 |
313 | +++ debian/changelog 2013-02-02 23:23:20 +0000 |
314 | @@ -1,3 +1,21 @@ |
315 | +nagios-nrpe (2.13-1ubuntu1) raring; urgency=low |
316 | + |
317 | + * Merge from Debian unstable. Remaining changes: |
318 | + - debian/{rules,control}: Add hardening-includes to gain PIE security |
319 | + builds. |
320 | + - debian/rules: Use dpkg-buildflags. |
321 | + |
322 | + -- Logan Rosen <logatronico@gmail.com> Sat, 02 Feb 2013 18:16:48 -0500 |
323 | + |
324 | +nagios-nrpe (2.13-1) unstable; urgency=low |
325 | + |
326 | + * [3e113b5] Imported Upstream version 2.13 |
327 | + * [acc152b] Bump standards version |
328 | + * [c707bce] Use dh9 for hardening |
329 | + * Updated patches |
330 | + |
331 | + -- Alexander Wirt <formorer@debian.org> Sat, 30 Jun 2012 11:08:22 +0200 |
332 | + |
333 | nagios-nrpe (2.12-6ubuntu2) quantal; urgency=low |
334 | |
335 | * Fixed compiler hardening configuration. (LP: #1000379) |
336 | |
337 | === modified file 'debian/compat' |
338 | --- debian/compat 2011-09-25 08:35:48 +0000 |
339 | +++ debian/compat 2013-02-02 23:23:20 +0000 |
340 | @@ -1,1 +1,1 @@ |
341 | -8 |
342 | +9 |
343 | |
344 | === modified file 'debian/control' |
345 | --- debian/control 2012-05-03 10:11:11 +0000 |
346 | +++ debian/control 2013-02-02 23:23:20 +0000 |
347 | @@ -4,8 +4,8 @@ |
348 | Maintainer: Ubuntu Developers <ubuntu-devel@lists.ubuntu.com> |
349 | XSBC-Original-Maintainer: Debian Nagios Maintainer Group <pkg-nagios-devel@lists.alioth.debian.org> |
350 | Uploaders: sean finney <seanius@debian.org>, Jason Thomas <jason@debian.org>, Alexander Wirt <formorer@debian.org>, Luk Claes <luk@debian.org> |
351 | -Build-Depends: debhelper (>= 8), openssl, dpatch (>= 2.0.32~), libssl-dev, libwrap0-dev, autotools-dev (>= 20100122.1), hardening-includes |
352 | -Standards-Version: 3.9.2 |
353 | +Build-Depends: debhelper (>= 9), openssl, dpatch (>= 2.0.32~), libssl-dev, libwrap0-dev, autotools-dev (>= 20100122.1), hardening-includes |
354 | +Standards-Version: 3.9.3 |
355 | |
356 | Package: nagios-nrpe-server |
357 | Architecture: any |
358 | |
359 | === modified file 'debian/patches/01_nodevrandom-and-docoptions.dpatch' |
360 | --- debian/patches/01_nodevrandom-and-docoptions.dpatch 2006-05-14 21:38:48 +0000 |
361 | +++ debian/patches/01_nodevrandom-and-docoptions.dpatch 2013-02-02 23:23:20 +0000 |
362 | @@ -5,58 +5,38 @@ |
363 | ## DP: No description. |
364 | |
365 | @DPATCH@ |
366 | -diff -urNad nagios-nrpe-2.2~/src/check_nrpe.c nagios-nrpe-2.2/src/check_nrpe.c |
367 | ---- nagios-nrpe-2.2~/src/check_nrpe.c 2006-01-21 20:23:36.000000000 +0100 |
368 | -+++ nagios-nrpe-2.2/src/check_nrpe.c 2006-01-24 08:36:39.000000000 +0100 |
369 | -@@ -93,6 +93,9 @@ |
370 | - printf(" [arglist] = Optional arguments that should be passed to the command. Multiple\n"); |
371 | - printf(" arguments should be separated by a space. If provided, this must be\n"); |
372 | - printf(" the last option supplied on the command line.\n"); |
373 | -+ printf(" -h,--help Print this short help.\n"); |
374 | -+ printf(" -l,--license Print licensing information.\n"); |
375 | -+ printf(" -n,--no-ssl Do not initial an ssl handshake with the server, talk in plaintext.\n"); |
376 | - printf("\n"); |
377 | - printf("Note:\n"); |
378 | - printf("This plugin requires that you have the NRPE daemon running on the remote host.\n"); |
379 | -diff -urNad nagios-nrpe-2.2~/src/nrpe.c nagios-nrpe-2.2/src/nrpe.c |
380 | ---- nagios-nrpe-2.2~/src/nrpe.c 2006-01-21 20:23:36.000000000 +0100 |
381 | -+++ nagios-nrpe-2.2/src/nrpe.c 2006-01-24 08:38:30.000000000 +0100 |
382 | -@@ -120,11 +120,13 @@ |
383 | - printf("Usage: nrpe [-n] -c <config_file> <mode>\n"); |
384 | - printf("\n"); |
385 | - printf("Options:\n"); |
386 | -- printf(" -n = Do not use SSL\n"); |
387 | -+ printf(" -n,--no-ssl = Do not use SSL\n"); |
388 | - printf(" <config_file> = Name of config file to use\n"); |
389 | - printf(" <mode> = One of the following two operating modes:\n"); |
390 | -- printf(" -i = Run as a service under inetd or xinetd\n"); |
391 | -- printf(" -d = Run as a standalone daemon\n"); |
392 | -+ printf(" -i,--inetd Run as a service under inetd or xinetd\n"); |
393 | -+ printf(" -d,--daemon Run as a standalone daemon\n"); |
394 | -+ printf(" -h,--help Print this short help.\n"); |
395 | -+ printf(" -l,--license Print licensing information.\n"); |
396 | - printf("\n"); |
397 | - printf("Notes:\n"); |
398 | - printf("This program is designed to process requests from the check_nrpe\n"); |
399 | -diff -urNad nagios-nrpe-2.2~/src/utils.c nagios-nrpe-2.2/src/utils.c |
400 | ---- nagios-nrpe-2.2~/src/utils.c 2003-10-16 01:14:27.000000000 +0200 |
401 | -+++ nagios-nrpe-2.2/src/utils.c 2006-01-24 08:36:39.000000000 +0100 |
402 | +diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' pkg-nrpe~/src/check_nrpe.c pkg-nrpe/src/check_nrpe.c |
403 | +--- pkg-nrpe~/src/check_nrpe.c 2012-04-30 09:36:53.000000000 +0200 |
404 | ++++ pkg-nrpe/src/check_nrpe.c 2012-04-30 09:45:36.129684439 +0200 |
405 | +@@ -96,6 +96,9 @@ |
406 | + printf(" [arglist] = Optional arguments that should be passed to the command. Multiple\n"); |
407 | + printf(" arguments should be separated by a space. If provided, this must be\n"); |
408 | + printf(" the last option supplied on the command line.\n"); |
409 | ++ printf(" -h,--help Print this short help.\n"); |
410 | ++ printf(" -l,--license Print licensing information.\n"); |
411 | ++ printf(" -n,--no-ssl Do not initiate an ssl handshake with the server, talk in plaintext.\n"); |
412 | + printf("\n"); |
413 | + printf("Note:\n"); |
414 | + printf("This plugin requires that you have the NRPE daemon running on the remote host.\n"); |
415 | +diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' pkg-nrpe~/src/utils.c pkg-nrpe/src/utils.c |
416 | +--- pkg-nrpe~/src/utils.c 2012-04-30 09:36:53.000000000 +0200 |
417 | ++++ pkg-nrpe/src/utils.c 2012-04-30 09:48:03.811163608 +0200 |
418 | @@ -90,17 +90,7 @@ |
419 | - ends and the rest of the buffer (padded randomly) starts. |
420 | - ***************************************************************/ |
421 | - |
422 | -- /* try to get seed value from /dev/urandom, as its a better source of entropy */ |
423 | -- fp=fopen("/dev/urandom","r"); |
424 | -- if(fp!=NULL){ |
425 | -- seed=fgetc(fp); |
426 | -- fclose(fp); |
427 | -- } |
428 | -- |
429 | -- /* else fallback to using the current time as the seed */ |
430 | -- else |
431 | -- seed=(int)time(NULL); |
432 | -- |
433 | -+ seed=(int)time(NULL)*311-getpid()*359+getppid()*383; |
434 | - srand(seed); |
435 | - for(x=0;x<buffer_size;x++) |
436 | - buffer[x]=(int)'0'+(int)(72.0*rand()/(RAND_MAX+1.0)); |
437 | + ends and the rest of the buffer (padded randomly) starts. |
438 | + ***************************************************************/ |
439 | + |
440 | +- /* try to get seed value from /dev/urandom, as its a better source of entropy */ |
441 | +- fp=fopen("/dev/urandom","r"); |
442 | +- if(fp!=NULL){ |
443 | +- seed=fgetc(fp); |
444 | +- fclose(fp); |
445 | +- } |
446 | +- |
447 | +- /* else fallback to using the current time as the seed */ |
448 | +- else |
449 | +- seed=(int)time(NULL); |
450 | +- |
451 | ++ seed=(int)time(NULL)*311-getpid()*359+getppid()*383; |
452 | + srand(seed); |
453 | + for(x=0;x<buffer_size;x++) |
454 | + buffer[x]=(int)'0'+(int)(72.0*rand()/(RAND_MAX+1.0)); |
455 | |
456 | === modified file 'debian/patches/04_weird_output.dpatch' |
457 | --- debian/patches/04_weird_output.dpatch 2009-03-21 09:33:39 +0000 |
458 | +++ debian/patches/04_weird_output.dpatch 2013-02-02 23:23:20 +0000 |
459 | @@ -5,16 +5,16 @@ |
460 | ## DP: Clean buffer before use |
461 | |
462 | @DPATCH@ |
463 | -diff -urNad nagios-nrpe-2.12~/src/nrpe.c nagios-nrpe-2.12/src/nrpe.c |
464 | ---- nagios-nrpe-2.12~/src/nrpe.c 2008-09-14 16:19:36.000000000 +0200 |
465 | -+++ nagios-nrpe-2.12/src/nrpe.c 2008-09-14 16:21:19.000000000 +0200 |
466 | -@@ -1165,6 +1165,9 @@ |
467 | - /* disable connection alarm - a new alarm will be setup during my_system */ |
468 | - alarm(0); |
469 | - |
470 | -+ // null buffer before using it! |
471 | -+ memset(buffer,0,sizeof(buffer)); |
472 | -+ |
473 | - /* if this is the version check command, just spew it out */ |
474 | - if(!strcmp(command_name,NRPE_HELLO_COMMAND)){ |
475 | - |
476 | +diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' pkg-nrpe~/src/nrpe.c pkg-nrpe/src/nrpe.c |
477 | +--- pkg-nrpe~/src/nrpe.c 2012-04-30 09:36:53.000000000 +0200 |
478 | ++++ pkg-nrpe/src/nrpe.c 2012-04-30 09:52:47.890535825 +0200 |
479 | +@@ -1107,6 +1107,9 @@ |
480 | + /* disable connection alarm - a new alarm will be setup during my_system */ |
481 | + alarm(0); |
482 | + |
483 | ++ // null buffer before using it! |
484 | ++ memset(buffer,0,sizeof(buffer)); |
485 | ++ |
486 | + /* if this is the version check command, just spew it out */ |
487 | + if(!strcmp(command_name,NRPE_HELLO_COMMAND)){ |
488 | + |
489 | |
490 | === modified file 'debian/patches/05_pid_privileges.dpatch' |
491 | --- debian/patches/05_pid_privileges.dpatch 2009-07-06 07:08:26 +0000 |
492 | +++ debian/patches/05_pid_privileges.dpatch 2013-02-02 23:23:20 +0000 |
493 | @@ -5,23 +5,23 @@ |
494 | ## DP: No description. |
495 | |
496 | @DPATCH@ |
497 | -diff -urNad nagios-nrpe-2.12~/src/nrpe.c nagios-nrpe-2.12/src/nrpe.c |
498 | ---- nagios-nrpe-2.12~/src/nrpe.c 2009-07-06 10:20:37.000000000 +0200 |
499 | -+++ nagios-nrpe-2.12/src/nrpe.c 2009-07-06 10:22:00.000000000 +0200 |
500 | -@@ -296,12 +296,13 @@ |
501 | - /* log info to syslog facility */ |
502 | - syslog(LOG_NOTICE,"Starting up daemon"); |
503 | - |
504 | -+ |
505 | -+ /* drop privileges */ |
506 | -+ drop_privileges(nrpe_user,nrpe_group); |
507 | -+ |
508 | - /* write pid file */ |
509 | - if(write_pid_file()==ERROR) |
510 | - return STATE_CRITICAL; |
511 | -- |
512 | -- /* drop privileges */ |
513 | -- drop_privileges(nrpe_user,nrpe_group); |
514 | - |
515 | - /* make sure we're not root */ |
516 | - check_privileges(); |
517 | +diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' pkg-nrpe~/src/nrpe.c pkg-nrpe/src/nrpe.c |
518 | +--- pkg-nrpe~/src/nrpe.c 2012-06-30 11:03:29.000000000 +0200 |
519 | ++++ pkg-nrpe/src/nrpe.c 2012-06-30 11:03:46.791280548 +0200 |
520 | +@@ -301,13 +301,13 @@ |
521 | + /* log info to syslog facility */ |
522 | + syslog(LOG_NOTICE,"Starting up daemon"); |
523 | + |
524 | ++ /* drop privileges */ |
525 | ++ drop_privileges(nrpe_user,nrpe_group); |
526 | ++ |
527 | + /* write pid file */ |
528 | + if(write_pid_file()==ERROR) |
529 | + return STATE_CRITICAL; |
530 | + |
531 | +- /* drop privileges */ |
532 | +- drop_privileges(nrpe_user,nrpe_group); |
533 | +- |
534 | + /* make sure we're not root */ |
535 | + check_privileges(); |
536 | + |
537 | |
538 | === modified file 'docs/NRPE.odt' (properties changed: -x to +x) |
539 | === modified file 'docs/NRPE.pdf' (properties changed: -x to +x) |
540 | === added file 'include/acl.h' |
541 | --- include/acl.h 1970-01-01 00:00:00 +0000 |
542 | +++ include/acl.h 2013-02-02 23:23:20 +0000 |
543 | @@ -0,0 +1,65 @@ |
544 | +/*- |
545 | + * acl.c - header file for acl.c |
546 | + * Copyright (c) 2011 Kaspersky Lab ZAO |
547 | + * Last Modified: 08-10-2011 by Konstantin Malov with Oleg Koreshkov's help |
548 | + * |
549 | + * License: GPL |
550 | + * |
551 | + * This program is free software; you can redistribute it and/or modify |
552 | + * it under the terms of the GNU General Public License as published by |
553 | + * the Free Software Foundation; either version 2 of the License, or |
554 | + * (at your option) any later version. |
555 | + * |
556 | + * This program is distributed in the hope that it will be useful, |
557 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
558 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
559 | + * GNU General Public License for more details. |
560 | + * |
561 | + * You should have received a copy of the GNU General Public License |
562 | + * along with this program; if not, write to the Free Software |
563 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
564 | + */ |
565 | + |
566 | +#ifndef ACL_H_INCLUDED |
567 | +#define ACL_H_INCLUDED 1 |
568 | + |
569 | +#include <sys/types.h> |
570 | +#include <sys/socket.h> |
571 | + |
572 | +#include <netinet/in.h> |
573 | +#include <arpa/inet.h> |
574 | + |
575 | +#include <stdio.h> |
576 | +#include <stdlib.h> |
577 | +#include <string.h> |
578 | +#include <ctype.h> |
579 | +#include <netdb.h> |
580 | +#include <syslog.h> |
581 | +#include <stdarg.h> |
582 | + |
583 | +#define CHAR_TO_NUMBER(c) ((c) - '0') |
584 | + |
585 | +struct ip_acl { |
586 | + struct in_addr addr; |
587 | + struct in_addr mask; |
588 | + struct ip_acl *next; |
589 | +}; |
590 | + |
591 | +struct dns_acl { |
592 | + char domain[255]; |
593 | + struct dns_acl *next; |
594 | +}; |
595 | + |
596 | +/* Poiters to head ACL structs */ |
597 | +static struct ip_acl *ip_acl_head, *ip_acl_prev; |
598 | +static struct dns_acl *dns_acl_head, *dns_acl_prev; |
599 | + |
600 | +/* Functions */ |
601 | +void parse_allowed_hosts(char *allowed_hosts); |
602 | +int add_ipv4_to_acl(char *ipv4); |
603 | +int add_domain_to_acl(char *domain); |
604 | +int is_an_allowed_host(struct in_addr); |
605 | +unsigned int prefix_from_mask(struct in_addr mask); |
606 | +void show_acl_lists(void); |
607 | + |
608 | +#endif /* ACL_H_INCLUDED */ |
609 | |
610 | === modified file 'include/common.h' (properties changed: -x to +x) |
611 | --- include/common.h 2008-08-06 20:33:57 +0000 |
612 | +++ include/common.h 2013-02-02 23:23:20 +0000 |
613 | @@ -1,71 +1,84 @@ |
614 | -/************************************************************************ |
615 | - * |
616 | - * COMMON.H - NRPE Common Include File |
617 | - * Copyright (c) 1999-2007 Ethan Galstad (nagios@nagios.org) |
618 | - * Last Modified: 03-10-2008 |
619 | - * |
620 | - * License: |
621 | - * |
622 | - * This program is free software; you can redistribute it and/or modify |
623 | - * it under the terms of the GNU General Public License as published by |
624 | - * the Free Software Foundation; either version 2 of the License, or |
625 | - * (at your option) any later version. |
626 | - * |
627 | - * This program is distributed in the hope that it will be useful, |
628 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
629 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
630 | - * GNU General Public License for more details. |
631 | - * |
632 | - * You should have received a copy of the GNU General Public License |
633 | - * along with this program; if not, write to the Free Software |
634 | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
635 | - ************************************************************************/ |
636 | - |
637 | -#include "config.h" |
638 | - |
639 | -#define PROGRAM_VERSION "2.12" |
640 | -#define MODIFICATION_DATE "03-10-2008" |
641 | - |
642 | -#define OK 0 |
643 | -#define ERROR -1 |
644 | - |
645 | -#define TRUE 1 |
646 | -#define FALSE 0 |
647 | - |
648 | -#define STATE_UNKNOWN 3 /* service state return codes */ |
649 | -#define STATE_CRITICAL 2 |
650 | -#define STATE_WARNING 1 |
651 | -#define STATE_OK 0 |
652 | - |
653 | - |
654 | -#define DEFAULT_SOCKET_TIMEOUT 10 /* timeout after 10 seconds */ |
655 | -#define DEFAULT_CONNECTION_TIMEOUT 300 /* timeout if daemon is waiting for connection more than this time */ |
656 | - |
657 | -#define MAX_INPUT_BUFFER 2048 /* max size of most buffers we use */ |
658 | -#define MAX_FILENAME_LENGTH 256 |
659 | - |
660 | -#define MAX_HOST_ADDRESS_LENGTH 256 /* max size of a host address */ |
661 | - |
662 | -#define NRPE_HELLO_COMMAND "_NRPE_CHECK" |
663 | - |
664 | -#define MAX_COMMAND_ARGUMENTS 16 |
665 | - |
666 | - |
667 | -/**************** PACKET STRUCTURE DEFINITION **********/ |
668 | - |
669 | -#define QUERY_PACKET 1 /* id code for a packet containing a query */ |
670 | -#define RESPONSE_PACKET 2 /* id code for a packet containing a response */ |
671 | - |
672 | -#define NRPE_PACKET_VERSION_3 3 /* packet version identifier */ |
673 | -#define NRPE_PACKET_VERSION_2 2 |
674 | -#define NRPE_PACKET_VERSION_1 1 /* older packet version identifiers (no longer supported) */ |
675 | - |
676 | -#define MAX_PACKETBUFFER_LENGTH 1024 /* max amount of data we'll send in one query/response */ |
677 | - |
678 | -typedef struct packet_struct{ |
679 | - int16_t packet_version; |
680 | - int16_t packet_type; |
681 | - u_int32_t crc32_value; |
682 | - int16_t result_code; |
683 | - char buffer[MAX_PACKETBUFFER_LENGTH]; |
684 | - }packet; |
685 | +/************************************************************************ |
686 | + * |
687 | + * COMMON.H - NRPE Common Include File |
688 | + * Copyright (c) 1999-2007 Ethan Galstad (nagios@nagios.org) |
689 | + * Last Modified: 11-11-2011 |
690 | + * |
691 | + * License: |
692 | + * |
693 | + * This program is free software; you can redistribute it and/or modify |
694 | + * it under the terms of the GNU General Public License as published by |
695 | + * the Free Software Foundation; either version 2 of the License, or |
696 | + * (at your option) any later version. |
697 | + * |
698 | + * This program is distributed in the hope that it will be useful, |
699 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
700 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
701 | + * GNU General Public License for more details. |
702 | + * |
703 | + * You should have received a copy of the GNU General Public License |
704 | + * along with this program; if not, write to the Free Software |
705 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
706 | + ************************************************************************/ |
707 | + |
708 | +#include "config.h" |
709 | + |
710 | +#define PROGRAM_VERSION "2.13" |
711 | +#define MODIFICATION_DATE "11-11-2011" |
712 | + |
713 | +#define OK 0 |
714 | +#define ERROR -1 |
715 | + |
716 | +#define TRUE 1 |
717 | +#define FALSE 0 |
718 | + |
719 | +#define STATE_UNKNOWN 3 /* service state return codes */ |
720 | +#define STATE_CRITICAL 2 |
721 | +#define STATE_WARNING 1 |
722 | +#define STATE_OK 0 |
723 | + |
724 | + |
725 | +#define DEFAULT_SOCKET_TIMEOUT 10 /* timeout after 10 seconds */ |
726 | +#define DEFAULT_CONNECTION_TIMEOUT 300 /* timeout if daemon is waiting for connection more than this time */ |
727 | + |
728 | +#define MAX_INPUT_BUFFER 2048 /* max size of most buffers we use */ |
729 | +#define MAX_FILENAME_LENGTH 256 |
730 | + |
731 | +#define MAX_HOST_ADDRESS_LENGTH 256 /* max size of a host address */ |
732 | + |
733 | +#define NRPE_HELLO_COMMAND "_NRPE_CHECK" |
734 | + |
735 | +#define MAX_COMMAND_ARGUMENTS 16 |
736 | + |
737 | + |
738 | +/**************** PACKET STRUCTURE DEFINITION **********/ |
739 | + |
740 | +#define QUERY_PACKET 1 /* id code for a packet containing a query */ |
741 | +#define RESPONSE_PACKET 2 /* id code for a packet containing a response */ |
742 | + |
743 | +#define NRPE_PACKET_VERSION_3 3 /* packet version identifier */ |
744 | +#define NRPE_PACKET_VERSION_2 2 |
745 | +#define NRPE_PACKET_VERSION_1 1 /* older packet version identifiers (no longer supported) */ |
746 | + |
747 | +#define MAX_PACKETBUFFER_LENGTH 1024 /* max amount of data we'll send in one query/response */ |
748 | + |
749 | +typedef struct packet_struct{ |
750 | + int16_t packet_version; |
751 | + int16_t packet_type; |
752 | + u_int32_t crc32_value; |
753 | + int16_t result_code; |
754 | + char buffer[MAX_PACKETBUFFER_LENGTH]; |
755 | + }packet; |
756 | + |
757 | +/**************** OPERATING SYSTEM SPECIFIC DEFINITIONS **********/ |
758 | +#ifdef __sun |
759 | + |
760 | +# ifndef LOG_AUTHPRIV |
761 | +# define LOG_AUTHPRIV LOG_AUTH |
762 | +# endif |
763 | + |
764 | +# ifndef LOG_FTP |
765 | +# define LOG_FTP LOG_DAEMON |
766 | +# endif |
767 | + |
768 | +#endif |
769 | |
770 | === modified file 'include/config.h.in' (properties changed: -x to +x) |
771 | === modified file 'include/dh.h' (properties changed: -x to +x) |
772 | --- include/dh.h 2008-08-06 20:33:57 +0000 |
773 | +++ include/dh.h 2013-02-02 23:23:20 +0000 |
774 | @@ -4,12 +4,12 @@ |
775 | DH *get_dh512() |
776 | { |
777 | static unsigned char dh512_p[]={ |
778 | - 0xA0,0xC9,0x8F,0x6D,0x75,0x7A,0x4E,0xED,0xED,0x80,0x11,0x32, |
779 | - 0x77,0x14,0xEA,0xE0,0xE7,0x38,0x55,0x01,0x03,0x02,0xC5,0x34, |
780 | - 0xCA,0x2D,0xA7,0xFA,0x2E,0x1C,0x5F,0xD9,0xF4,0xDA,0x54,0x40, |
781 | - 0xD7,0xB4,0x7B,0x00,0xE5,0x19,0x30,0x69,0xC5,0x93,0x52,0x09, |
782 | - 0xB7,0x2D,0x5B,0xAB,0x27,0x0C,0x0D,0xAA,0xCE,0x56,0xB7,0x4D, |
783 | - 0xE9,0x8A,0xFB,0x43, |
784 | + 0xA4,0x56,0x47,0x7F,0x90,0xF0,0xDE,0xFE,0x73,0x1A,0xBD,0x3E, |
785 | + 0xA9,0xF5,0x69,0x46,0x29,0x0B,0x47,0x55,0x8C,0xE8,0xF3,0xDF, |
786 | + 0xF6,0x1B,0xC5,0x29,0x1B,0x81,0x97,0x3E,0xE4,0xD9,0xC8,0x2B, |
787 | + 0xBB,0x2B,0x7A,0x37,0xE1,0x18,0xDF,0xEC,0x6B,0xEC,0x04,0x77, |
788 | + 0x6D,0x51,0x3C,0x7C,0xB7,0x81,0xBD,0x7F,0xC9,0x5A,0x04,0xB4, |
789 | + 0xA4,0x3E,0x8B,0x5B, |
790 | }; |
791 | static unsigned char dh512_g[]={ |
792 | 0x02, |
793 | |
794 | === modified file 'include/nrpe.h' (properties changed: -x to +x) |
795 | --- include/nrpe.h 2008-08-06 20:33:57 +0000 |
796 | +++ include/nrpe.h 2013-02-02 23:23:20 +0000 |
797 | @@ -1,61 +1,65 @@ |
798 | -/************************************************************************ |
799 | - * |
800 | - * NRPE.H - NRPE Include File |
801 | - * Copyright (c) 1999-2007 Ethan Galstad (nagios@nagios.org) |
802 | - * Last Modified: 11-23-2007 |
803 | - * |
804 | - * License: |
805 | - * |
806 | - * This program is free software; you can redistribute it and/or modify |
807 | - * it under the terms of the GNU General Public License as published by |
808 | - * the Free Software Foundation; either version 2 of the License, or |
809 | - * (at your option) any later version. |
810 | - * |
811 | - * This program is distributed in the hope that it will be useful, |
812 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
813 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
814 | - * GNU General Public License for more details. |
815 | - * |
816 | - * You should have received a copy of the GNU General Public License |
817 | - * along with this program; if not, write to the Free Software |
818 | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
819 | - * |
820 | - ************************************************************************/ |
821 | - |
822 | - |
823 | -/**************** COMMAND STRUCTURE DEFINITION **********/ |
824 | - |
825 | -typedef struct command_struct{ |
826 | - char *command_name; |
827 | - char *command_line; |
828 | - struct command_struct *next; |
829 | - }command; |
830 | - |
831 | -int process_arguments(int,char **); |
832 | -void wait_for_connections(void); |
833 | -void handle_connection(int); |
834 | -int read_config_file(char *); |
835 | -int read_config_dir(char *); |
836 | -int get_log_facility(char *); |
837 | -int add_command(char *,char *); |
838 | -command *find_command(char *); |
839 | -void sighandler(int); |
840 | -int drop_privileges(char *,char *); |
841 | -int check_privileges(void); |
842 | - |
843 | -int write_pid_file(void); |
844 | -int remove_pid_file(void); |
845 | - |
846 | -void free_memory(void); |
847 | -int is_an_allowed_host(char *); |
848 | -int validate_request(packet *); |
849 | -int contains_nasty_metachars(char *); |
850 | -int process_macros(char *,char *,int); |
851 | -int my_system(char *,int,int *,char *,int); /* executes a command via popen(), but also protects against timeouts */ |
852 | -void my_system_sighandler(int); /* handles timeouts when executing commands via my_system() */ |
853 | -void my_connection_sighandler(int); /* handles timeouts of connection */ |
854 | - |
855 | -void sighandler(int); |
856 | -void child_sighandler(int); |
857 | - |
858 | - |
859 | +/************************************************************************ |
860 | + * |
861 | + * NRPE.H - NRPE Include File |
862 | + * Copyright (c) 1999-2007 Ethan Galstad (nagios@nagios.org) |
863 | + * Last Modified: 08-10-2011 by Konstantin Malov |
864 | + * |
865 | + * License: |
866 | + * |
867 | + * This program is free software; you can redistribute it and/or modify |
868 | + * it under the terms of the GNU General Public License as published by |
869 | + * the Free Software Foundation; either version 2 of the License, or |
870 | + * (at your option) any later version. |
871 | + * |
872 | + * This program is distributed in the hope that it will be useful, |
873 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
874 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
875 | + * GNU General Public License for more details. |
876 | + * |
877 | + * You should have received a copy of the GNU General Public License |
878 | + * along with this program; if not, write to the Free Software |
879 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
880 | + * |
881 | + ************************************************************************/ |
882 | + |
883 | + /* |
884 | + * 08-10-2011 IPv4 subnetworks support added. |
885 | + * Main change in nrpe.c is that is_an_allowed_host() moved to acl.c |
886 | + * |
887 | + */ |
888 | + |
889 | +/**************** COMMAND STRUCTURE DEFINITION **********/ |
890 | + |
891 | +typedef struct command_struct{ |
892 | + char *command_name; |
893 | + char *command_line; |
894 | + struct command_struct *next; |
895 | + }command; |
896 | + |
897 | +int process_arguments(int,char **); |
898 | +void wait_for_connections(void); |
899 | +void handle_connection(int); |
900 | +int read_config_file(char *); |
901 | +int read_config_dir(char *); |
902 | +int get_log_facility(char *); |
903 | +int add_command(char *,char *); |
904 | +command *find_command(char *); |
905 | +void sighandler(int); |
906 | +int drop_privileges(char *,char *); |
907 | +int check_privileges(void); |
908 | + |
909 | +int write_pid_file(void); |
910 | +int remove_pid_file(void); |
911 | + |
912 | +void free_memory(void); |
913 | +int validate_request(packet *); |
914 | +int contains_nasty_metachars(char *); |
915 | +int process_macros(char *,char *,int); |
916 | +int my_system(char *,int,int *,char *,int); /* executes a command via popen(), but also protects against timeouts */ |
917 | +void my_system_sighandler(int); /* handles timeouts when executing commands via my_system() */ |
918 | +void my_connection_sighandler(int); /* handles timeouts of connection */ |
919 | + |
920 | +void sighandler(int); |
921 | +void child_sighandler(int); |
922 | + |
923 | + |
924 | |
925 | === modified file 'include/utils.h' (properties changed: -x to +x) |
926 | --- include/utils.h 2007-05-12 12:27:30 +0000 |
927 | +++ include/utils.h 2013-02-02 23:23:20 +0000 |
928 | @@ -1,62 +1,62 @@ |
929 | -/************************************************************************************************ |
930 | - * |
931 | - * UTILS.H - NRPE Utilities Include File |
932 | - * |
933 | - * License: GPL |
934 | - * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) |
935 | - * |
936 | - * Last Modified: 12-11-2006 |
937 | - * |
938 | - * Description: |
939 | - * |
940 | - * This file contains common include files and function definitions used in many of the plugins. |
941 | - * |
942 | - * License Information: |
943 | - * |
944 | - * This program is free software; you can redistribute it and/or modify |
945 | - * it under the terms of the GNU General Public License as published by |
946 | - * the Free Software Foundation; either version 2 of the License, or |
947 | - * (at your option) any later version. |
948 | - * |
949 | - * This program is distributed in the hope that it will be useful, |
950 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
951 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
952 | - * GNU General Public License for more details. |
953 | - * |
954 | - * You should have received a copy of the GNU General Public License |
955 | - * along with this program; if not, write to the Free Software |
956 | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
957 | - * |
958 | - ************************************************************************************************/ |
959 | - |
960 | -#ifndef _UTILS_H |
961 | -#define _UTILS_H |
962 | - |
963 | -#include "../include/config.h" |
964 | - |
965 | - |
966 | -void generate_crc32_table(void); |
967 | -unsigned long calculate_crc32(char *, int); |
968 | - |
969 | -void randomize_buffer(char *,int); |
970 | - |
971 | -int my_tcp_connect(char *,int,int *); |
972 | -int my_connect(char *,int,int *,char *); |
973 | - |
974 | -int my_inet_aton(register const char *,struct in_addr *); |
975 | - |
976 | -void strip(char *); |
977 | - |
978 | -int sendall(int,char *,int *); |
979 | -int recvall(int,char *,int *,int); |
980 | - |
981 | -char *my_strsep(char **,const char *); |
982 | - |
983 | -void display_license(void); |
984 | - |
985 | -#endif |
986 | - |
987 | - |
988 | - |
989 | - |
990 | - |
991 | +/************************************************************************************************ |
992 | + * |
993 | + * UTILS.H - NRPE Utilities Include File |
994 | + * |
995 | + * License: GPL |
996 | + * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) |
997 | + * |
998 | + * Last Modified: 12-11-2006 |
999 | + * |
1000 | + * Description: |
1001 | + * |
1002 | + * This file contains common include files and function definitions used in many of the plugins. |
1003 | + * |
1004 | + * License Information: |
1005 | + * |
1006 | + * This program is free software; you can redistribute it and/or modify |
1007 | + * it under the terms of the GNU General Public License as published by |
1008 | + * the Free Software Foundation; either version 2 of the License, or |
1009 | + * (at your option) any later version. |
1010 | + * |
1011 | + * This program is distributed in the hope that it will be useful, |
1012 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1013 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1014 | + * GNU General Public License for more details. |
1015 | + * |
1016 | + * You should have received a copy of the GNU General Public License |
1017 | + * along with this program; if not, write to the Free Software |
1018 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
1019 | + * |
1020 | + ************************************************************************************************/ |
1021 | + |
1022 | +#ifndef _UTILS_H |
1023 | +#define _UTILS_H |
1024 | + |
1025 | +#include "../include/config.h" |
1026 | + |
1027 | + |
1028 | +void generate_crc32_table(void); |
1029 | +unsigned long calculate_crc32(char *, int); |
1030 | + |
1031 | +void randomize_buffer(char *,int); |
1032 | + |
1033 | +int my_tcp_connect(char *,int,int *); |
1034 | +int my_connect(char *,int,int *,char *); |
1035 | + |
1036 | +int my_inet_aton(register const char *,struct in_addr *); |
1037 | + |
1038 | +void strip(char *); |
1039 | + |
1040 | +int sendall(int,char *,int *); |
1041 | +int recvall(int,char *,int *,int); |
1042 | + |
1043 | +char *my_strsep(char **,const char *); |
1044 | + |
1045 | +void display_license(void); |
1046 | + |
1047 | +#endif |
1048 | + |
1049 | + |
1050 | + |
1051 | + |
1052 | + |
1053 | |
1054 | === modified file 'init-script.debian.in' (properties changed: -x to +x) |
1055 | === modified file 'init-script.in' (properties changed: -x to +x) |
1056 | === modified file 'init-script.suse.in' (properties changed: -x to +x) |
1057 | === modified file 'nrpe.spec' (properties changed: -x to +x) |
1058 | --- nrpe.spec 2008-08-06 20:33:57 +0000 |
1059 | +++ nrpe.spec 2013-02-02 23:23:20 +0000 |
1060 | @@ -1,5 +1,5 @@ |
1061 | %define name nrpe |
1062 | -%define version 2.12 |
1063 | +%define version 2.13 |
1064 | %define release 1 |
1065 | %define nsusr nagios |
1066 | %define nsgrp nagios |
1067 | |
1068 | === modified file 'sample-config/nrpe.cfg.in' (properties changed: -x to +x) |
1069 | --- sample-config/nrpe.cfg.in 2008-08-06 20:33:57 +0000 |
1070 | +++ sample-config/nrpe.cfg.in 2013-02-02 23:23:20 +0000 |
1071 | @@ -67,7 +67,9 @@ |
1072 | |
1073 | # ALLOWED HOST ADDRESSES |
1074 | # This is an optional comma-delimited list of IP address or hostnames |
1075 | -# that are allowed to talk to the NRPE daemon. |
1076 | +# that are allowed to talk to the NRPE daemon. Network addresses with a bit mask |
1077 | +# (i.e. 192.168.1.0/24) are also supported. Hostname wildcards are not currently |
1078 | +# supported. |
1079 | # |
1080 | # Note: The daemon only does rudimentary checking of the client's IP |
1081 | # address. I would highly recommend adding entries in your /etc/hosts.allow |
1082 | |
1083 | === modified file 'sample-config/nrpe.xinetd.in' (properties changed: -x to +x) |
1084 | === removed file 'src/.cvsignore' |
1085 | --- src/.cvsignore 2011-10-18 15:09:21 +0000 |
1086 | +++ src/.cvsignore 1970-01-01 00:00:00 +0000 |
1087 | @@ -1,1 +0,0 @@ |
1088 | -dh.h |
1089 | |
1090 | === modified file 'src/Makefile.in' (properties changed: -x to +x) |
1091 | --- src/Makefile.in 2008-08-06 20:33:57 +0000 |
1092 | +++ src/Makefile.in 2013-02-02 23:23:20 +0000 |
1093 | @@ -33,8 +33,8 @@ |
1094 | |
1095 | all: nrpe check_nrpe |
1096 | |
1097 | -nrpe: nrpe.c utils.c $(SRC_INCLUDE)/nrpe.h $(SRC_INCLUDE)/utils.h $(SRC_INCLUDE)/common.h $(SRC_INCLUDE)/config.h $(SNPRINTF_O) |
1098 | - $(CC) $(CFLAGS) -o $@ nrpe.c utils.c $(LDFLAGS) $(SOCKETLIBS) $(LIBWRAPLIBS) $(SNPRINTF_O) $(OTHERLIBS) |
1099 | +nrpe: nrpe.c utils.c acl.c $(SRC_INCLUDE)/nrpe.h $(SRC_INCLUDE)/utils.h $(SRC_INCLUDE)/common.h $(SRC_INCLUDE)/config.h $(SRC_INCLUDE)/acl.h $(SNPRINTF_O) |
1100 | + $(CC) $(CFLAGS) -o $@ nrpe.c utils.c acl.c $(LDFLAGS) $(SOCKETLIBS) $(LIBWRAPLIBS) $(SNPRINTF_O) $(OTHERLIBS) |
1101 | |
1102 | check_nrpe: check_nrpe.c utils.c $(SRC_INCLUDE)/utils.h $(SRC_INCLUDE)/common.h $(SRC_INCLUDE)/config.h |
1103 | $(CC) $(CFLAGS) -o $@ check_nrpe.c utils.c $(LDFLAGS) $(SOCKETLIBS) $(OTHERLIBS) |
1104 | |
1105 | === added file 'src/acl.c' |
1106 | --- src/acl.c 1970-01-01 00:00:00 +0000 |
1107 | +++ src/acl.c 2013-02-02 23:23:20 +0000 |
1108 | @@ -0,0 +1,469 @@ |
1109 | +/*- |
1110 | + * acl.c - a small library for nrpe.c. It adds IPv4 subnets support to ACL in nrpe. |
1111 | + * Copyright (c) 2011 Kaspersky Lab ZAO |
1112 | + * Last Modified: 08-10-2011 by Konstantin Malov with Oleg Koreshkov's help |
1113 | + * |
1114 | + * Description: |
1115 | + * acl.c creates two linked lists. One is for IPv4 hosts and networks, another is for domain names. |
1116 | + * All connecting hosts (if allowed_hosts is defined) are checked in these two lists. |
1117 | + * |
1118 | + * Some notes: |
1119 | + * 1) IPv6 isn't supported in ACL. |
1120 | + * 2) Only ANCII names are supported in ACL. |
1121 | + * |
1122 | + * License: GPL |
1123 | + * |
1124 | + * This program is free software; you can redistribute it and/or modify |
1125 | + * it under the terms of the GNU General Public License as published by |
1126 | + * the Free Software Foundation; either version 2 of the License, or |
1127 | + * (at your option) any later version. |
1128 | + * |
1129 | + * This program is distributed in the hope that it will be useful, |
1130 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1131 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1132 | + * GNU General Public License for more details. |
1133 | + * |
1134 | + * You should have received a copy of the GNU General Public License |
1135 | + * along with this program; if not, write to the Free Software |
1136 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
1137 | + */ |
1138 | + |
1139 | +#include <sys/types.h> |
1140 | +#include <sys/socket.h> |
1141 | + |
1142 | +#include <netinet/in.h> |
1143 | +#include <arpa/inet.h> |
1144 | + |
1145 | +#include <stdio.h> |
1146 | +#include <stdlib.h> |
1147 | +#include <string.h> |
1148 | +#include <ctype.h> |
1149 | +#include <netdb.h> |
1150 | +#include <syslog.h> |
1151 | +#include <stdarg.h> |
1152 | + |
1153 | +#include "../include/acl.h" |
1154 | + |
1155 | +/* This function checks if a char argumnet from valid char range. |
1156 | + * Valid range is: ASCII only, a number or a letter, a space, a dot, a slash, a dash, a comma. |
1157 | + * |
1158 | + * Returns: |
1159 | + * 0 - char isn't from valid group |
1160 | + * 1 - char is a number |
1161 | + * 2 - char is a letter |
1162 | + * 3 - char is a space(' ') |
1163 | + * 4 - char is a dot('.') |
1164 | + * 5 - char is a slash('/') |
1165 | + * 6 - char is a dash('-') |
1166 | + * 7 - char is a comma(',') |
1167 | + */ |
1168 | + |
1169 | +int isvalidchar(int c) { |
1170 | + if (!isascii(c)) |
1171 | + return 0; |
1172 | + |
1173 | + if (isdigit(c)) |
1174 | + return 1; |
1175 | + |
1176 | + if (isalpha(c)) |
1177 | + return 2; |
1178 | + |
1179 | + if (isspace(c)) |
1180 | + return 3; |
1181 | + |
1182 | + switch (c) { |
1183 | + case '.': |
1184 | + return 4; |
1185 | + break; |
1186 | + case '/': |
1187 | + return 5; |
1188 | + break; |
1189 | + case '-': |
1190 | + return 6; |
1191 | + break; |
1192 | + case ',': |
1193 | + return 7; |
1194 | + break; |
1195 | + default: |
1196 | + return 0; |
1197 | + } |
1198 | +} |
1199 | + |
1200 | +/* |
1201 | + * Get substring from allowed_hosts from s position to e position. |
1202 | + */ |
1203 | + |
1204 | +char * acl_substring(char *string, int s, int e) { |
1205 | + char *substring; |
1206 | + int len = e - s; |
1207 | + |
1208 | + if (len < 0) |
1209 | + return NULL; |
1210 | + |
1211 | + if ( (substring = malloc(len + 1)) == NULL) |
1212 | + return NULL; |
1213 | + |
1214 | + memmove(substring, string + s, len + 1); |
1215 | + return substring; |
1216 | +} |
1217 | + |
1218 | +/* |
1219 | + * Add IPv4 host or network to IP ACL. IPv4 format is X.X.X.X[/X]. |
1220 | + * Host will be added to ACL only if it has passed IPv4 format check. |
1221 | + * |
1222 | + * Returns: |
1223 | + * 1 - on success |
1224 | + * 0 - on failure |
1225 | + * |
1226 | + * States for IPv4 format check: |
1227 | + * 0 - numbers(-> 1), dot(-> -1), slash(-> -1), other(-> -1) |
1228 | + * 1 - numbers(-> 1), dot(-> 2), slash(-> -1), other(-> -1) |
1229 | + * 2 - numbers(-> 3), dot(-> -1), slash(-> -1), other(-> -1) |
1230 | + * 3 - numbers(-> 3), dot(-> 4), slash(-> -1), other(-> -1) |
1231 | + * 4 - numbers(-> 5), dot(-> -1), slash(-> -1), other(-> -1) |
1232 | + * 5 - numbers(-> 5), dot(-> 6), slash(-> -1), other(-> -1) |
1233 | + * 6 - numbers(-> 7), dot(-> -1), slash(-> -1), other(-> -1) |
1234 | + * 7 - numbers(-> 7), dor(-> -1), slash(-> 8), other(-> -1) |
1235 | + * 8 - numbers(-> 9), dor(-> -1), slash(-> -1), other(-> -1) |
1236 | + * 9 - numbers(-> 9), dot(-> -1), slash(-> -1), other(-> -1) |
1237 | + * |
1238 | + * Good states are 7(IPv4 host) and 9(IPv4 network) |
1239 | + */ |
1240 | + |
1241 | +int add_ipv4_to_acl(char *ipv4) { |
1242 | + int state = 0; |
1243 | + int octet = 0; |
1244 | + int index = 0; /* position in data array */ |
1245 | + int data[5]; /* array to store ip octets and mask */ |
1246 | + int len = strlen(ipv4); |
1247 | + int i, c; |
1248 | + unsigned long ip, mask; |
1249 | + struct ip_acl *ip_acl_curr; |
1250 | + |
1251 | + /* Check for min and max IPv4 valid length */ |
1252 | + if (len < 7 || len > 18) |
1253 | + return 0; |
1254 | + |
1255 | + /* default mask for ipv4 */ |
1256 | + data[4] = 32; |
1257 | + |
1258 | + /* Basic IPv4 format check */ |
1259 | + for (i = 0; i < len; i++) { |
1260 | + /* Return 0 on error state */ |
1261 | + if (state == -1) |
1262 | + return 0; |
1263 | + |
1264 | + c = ipv4[i]; |
1265 | + |
1266 | + switch (c) { |
1267 | + case '0': case '1': case '2': case '3': case '4': |
1268 | + case '5': case '6': case '7': case '8': case '9': |
1269 | + octet = octet * 10 + CHAR_TO_NUMBER(c); |
1270 | + switch (state) { |
1271 | + case 0: case 2: case 4: case 6: case 8: |
1272 | + state++; |
1273 | + break; |
1274 | + } |
1275 | + break; |
1276 | + case '.': |
1277 | + switch (state) { |
1278 | + case 1: case 3: case 5: |
1279 | + data[index++] = octet; |
1280 | + octet = 0; |
1281 | + state++; |
1282 | + break; |
1283 | + default: |
1284 | + state = -1; |
1285 | + } |
1286 | + break; |
1287 | + case '/': |
1288 | + switch (state) { |
1289 | + case 7: |
1290 | + data[index++] = octet; |
1291 | + octet = 0; |
1292 | + state++; |
1293 | + break; |
1294 | + default: |
1295 | + state = -1; |
1296 | + } |
1297 | + break; |
1298 | + default: |
1299 | + state = -1; |
1300 | + } |
1301 | + } |
1302 | + |
1303 | + /* Exit state handling */ |
1304 | + switch (state) { |
1305 | + case 7: case 9: |
1306 | + data[index] = octet; |
1307 | + break; |
1308 | + default: |
1309 | + /* Bad states */ |
1310 | + return 0; |
1311 | + } |
1312 | + |
1313 | + /* |
1314 | + * Final IPv4 format check. |
1315 | + */ |
1316 | + for (i=0; i < 4; i++) { |
1317 | + if (data[i] < 0 || data[i] > 255) { |
1318 | + syslog(LOG_ERR,"Invalid IPv4 address/network format(%s) in allowed_hosts option\n",ipv4); |
1319 | + return 0; |
1320 | + } |
1321 | + } |
1322 | + |
1323 | + if (data[4] < 0 || data[4] > 32) { |
1324 | + syslog(LOG_ERR,"Invalid IPv4 network mask format(%s) in allowed_hosts option\n",ipv4); |
1325 | + return 0; |
1326 | + } |
1327 | + |
1328 | + /* Conver ip and mask to unsigned long */ |
1329 | + ip = htonl((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]); |
1330 | + mask = htonl(-1 << (32 - data[4])); |
1331 | + |
1332 | + /* Wrong network address */ |
1333 | + if ( (ip & mask) != ip) { |
1334 | + syslog(LOG_ERR,"IP address and mask do not match in %s\n",ipv4); |
1335 | + return 0; |
1336 | + } |
1337 | + |
1338 | + /* Add addr to ip_acl list */ |
1339 | + if ( (ip_acl_curr = malloc(sizeof(*ip_acl_curr))) == NULL) { |
1340 | + syslog(LOG_ERR,"Can't allocate memory for ACL, malloc error\n"); |
1341 | + return 0; |
1342 | + } |
1343 | + |
1344 | + /* Save result in ACL ip list */ |
1345 | + ip_acl_curr->addr.s_addr = ip; |
1346 | + ip_acl_curr->mask.s_addr = mask; |
1347 | + ip_acl_curr->next = NULL; |
1348 | + |
1349 | + if (ip_acl_head == NULL) { |
1350 | + ip_acl_head = ip_acl_curr; |
1351 | + } else { |
1352 | + ip_acl_prev->next = ip_acl_curr; |
1353 | + } |
1354 | + ip_acl_prev = ip_acl_curr; |
1355 | + return 1; |
1356 | +} |
1357 | + |
1358 | +/* |
1359 | + * Add domain to DNS ACL list |
1360 | + * Domain will be added only if it has passed domain name check. |
1361 | + * |
1362 | + * In this case domain valid format is: |
1363 | + * 1) Domain names must use only alphanumeric characters and dashes (-). |
1364 | + * 2) Domain names mustn't begin or end with dashes (-). |
1365 | + * 3) Domain names mustn't have more than 63 characters. |
1366 | + * |
1367 | + * Return: |
1368 | + * 1 - for success |
1369 | + * 0 - for failure |
1370 | + * |
1371 | + * 0 - alpha(-> 1), number(-> 1), dot(-> -1), dash(-> -1), all other(-> -1) |
1372 | + * 1 - alpha(-> 1), number(-> 1), dot(-> 2), dash(-> 6), all other(-> -1) |
1373 | + * 2 - alpha(-> 3), number(-> 1), dot(-> -1), dash(-> -1), all other(-> -1) |
1374 | + * 3 - alpha(-> 4), number(-> 1), dot(-> 2), dash(-> 6), all other(-> -1) |
1375 | + * 4 - alpha(-> 5), number(-> 1), dot(-> 2), dash(-> 6), all other(-> -1) |
1376 | + * 5 - alpha(-> 1), number(-> 1), dot(-> 2), dash(-> 6), all other(-> -1) |
1377 | + * 6 - alpha(-> 1), number(-> 1), dot(-> 2), dash(-> 6), all other(-> -1) |
1378 | + |
1379 | + * For real FQDN only 4 and 5 states are good for exit. |
1380 | + * I don't check if top domain exists (com, ru and etc.) |
1381 | + * But in real life NRPE could work in LAN, |
1382 | + * with local domain zones like .local or with names like 'mars' added to /etc/hosts. |
1383 | + * So 1 is good state too. And maybe this check is not necessary at all... |
1384 | + */ |
1385 | + |
1386 | +int add_domain_to_acl(char *domain) { |
1387 | + int state = 0; |
1388 | + int len = strlen(domain); |
1389 | + int i, c; |
1390 | + |
1391 | + struct dns_acl *dns_acl_curr; |
1392 | + |
1393 | + if (len > 63) |
1394 | + return 0; |
1395 | + |
1396 | + for (i = 0; i < len; i++) { |
1397 | + c = domain[i]; |
1398 | + switch (isvalidchar(c)) { |
1399 | + case 1: |
1400 | + state = 1; |
1401 | + break; |
1402 | + case 2: |
1403 | + switch (state) { |
1404 | + case 0: case 1: case 5: case 6: |
1405 | + state = 1; |
1406 | + break; |
1407 | + case 2: case 3: case 4: |
1408 | + state++; |
1409 | + break; |
1410 | + } |
1411 | + break; |
1412 | + |
1413 | + case 4: |
1414 | + switch (state) { |
1415 | + case 0: case 2: |
1416 | + state = -1; |
1417 | + break; |
1418 | + default: |
1419 | + state = 2; |
1420 | + } |
1421 | + break; |
1422 | + case 6: |
1423 | + switch (state) { |
1424 | + case 0: case 2: |
1425 | + state = -1; |
1426 | + break; |
1427 | + default: |
1428 | + state = 6; |
1429 | + } |
1430 | + break; |
1431 | + default: |
1432 | + /* Not valid chars */ |
1433 | + return 0; |
1434 | + } |
1435 | + } |
1436 | + |
1437 | + /* Check exit code */ |
1438 | + switch (state) { |
1439 | + case 1: case 4: case 5: |
1440 | + /* Add name to domain ACL list */ |
1441 | + if ( (dns_acl_curr = malloc(sizeof(*dns_acl_curr))) == NULL) { |
1442 | + syslog(LOG_ERR,"Can't allocate memory for ACL, malloc error\n"); |
1443 | + return 0; |
1444 | + } |
1445 | + strcpy(dns_acl_curr->domain, domain); |
1446 | + dns_acl_curr->next = NULL; |
1447 | + |
1448 | + if (dns_acl_head == NULL) |
1449 | + dns_acl_head = dns_acl_curr; |
1450 | + else |
1451 | + dns_acl_prev->next = dns_acl_curr; |
1452 | + |
1453 | + dns_acl_prev = dns_acl_curr; |
1454 | + return 1; |
1455 | + default: |
1456 | + return 0; |
1457 | + } |
1458 | +} |
1459 | + |
1460 | +/* Checks connectiong host in ACL |
1461 | + * |
1462 | + * Returns: |
1463 | + * 1 - on success |
1464 | + * 0 - on failure |
1465 | + */ |
1466 | + |
1467 | +int is_an_allowed_host(struct in_addr host) { |
1468 | + struct ip_acl *ip_acl_curr = ip_acl_head; |
1469 | + struct dns_acl *dns_acl_curr = dns_acl_head; |
1470 | + struct in_addr addr; |
1471 | + struct hostent *he; |
1472 | + |
1473 | + while (ip_acl_curr != NULL) { |
1474 | + if ( (host.s_addr & ip_acl_curr->mask.s_addr) == ip_acl_curr->addr.s_addr) |
1475 | + return 1; |
1476 | + |
1477 | + ip_acl_curr = ip_acl_curr->next; |
1478 | + } |
1479 | + |
1480 | + while(dns_acl_curr != NULL) { |
1481 | + he = gethostbyname(dns_acl_curr->domain); |
1482 | + if (he == NULL) |
1483 | + return 0; |
1484 | + |
1485 | + while (*he->h_addr_list) { |
1486 | + memmove((char *)&addr,*he->h_addr_list++, sizeof(addr)); |
1487 | + if (addr.s_addr == host.s_addr) |
1488 | + return 1; |
1489 | + } |
1490 | + dns_acl_curr = dns_acl_curr->next; |
1491 | + } |
1492 | + return 0; |
1493 | +} |
1494 | + |
1495 | +/* The trim() function takes a source string and copies it to the destination string, |
1496 | + * stripped of leading and training whitespace. The destination string must be |
1497 | + * allocated at least as large as the source string. |
1498 | + */ |
1499 | + |
1500 | +void trim( char *src, char *dest) { |
1501 | + char *sptr, *dptr; |
1502 | + |
1503 | + for( sptr = src; isblank( *sptr) && *sptr; sptr++); /* Jump past leading spaces */ |
1504 | + for( dptr = dest; !isblank( *sptr) && *sptr; ) { |
1505 | + *dptr = *sptr; |
1506 | + sptr++; |
1507 | + dptr++; |
1508 | + } |
1509 | + *dptr = '\0'; |
1510 | + return; |
1511 | +} |
1512 | + |
1513 | +/* This function splits allowed_hosts to substrings with comma(,) as a delimeter. |
1514 | + * It doesn't check validness of ACL record (add_ipv4_to_acl() and add_domain_to_acl() do), |
1515 | + * just trims spaces from ACL records. |
1516 | + * After this it sends ACL records to add_ipv4_to_acl() or add_domain_to_acl(). |
1517 | + */ |
1518 | + |
1519 | +void parse_allowed_hosts(char *allowed_hosts) { |
1520 | + char *hosts = strdup( allowed_hosts); /* Copy since strtok* modifes original */ |
1521 | + char *saveptr; |
1522 | + char *tok; |
1523 | + const char *delim = ","; |
1524 | + char *trimmed_tok; |
1525 | + |
1526 | + tok = strtok_r( hosts, delim, &saveptr); |
1527 | + while( tok) { |
1528 | + trimmed_tok = malloc( sizeof( char) * ( strlen( tok) + 1)); |
1529 | + trim( tok, trimmed_tok); |
1530 | + if( strlen( trimmed_tok) > 0) { |
1531 | + if (!add_ipv4_to_acl(trimmed_tok) && !add_domain_to_acl(trimmed_tok)) { |
1532 | + syslog(LOG_ERR,"Can't add to ACL this record (%s). Check allowed_hosts option!\n",trimmed_tok); |
1533 | + } |
1534 | + } |
1535 | + free( trimmed_tok); |
1536 | + tok = strtok_r(( char *)0, delim, &saveptr); |
1537 | + } |
1538 | + |
1539 | + free( hosts); |
1540 | +} |
1541 | + |
1542 | +/* |
1543 | + * Converts mask in unsigned long format to two digit prefix |
1544 | + */ |
1545 | + |
1546 | +unsigned int prefix_from_mask(struct in_addr mask) { |
1547 | + int prefix = 0; |
1548 | + unsigned long bit = 1; |
1549 | + int i; |
1550 | + |
1551 | + for (i = 0; i < 32; i++) { |
1552 | + if (mask.s_addr & bit) |
1553 | + prefix++; |
1554 | + |
1555 | + bit = bit << 1; |
1556 | + } |
1557 | + return (prefix); |
1558 | +} |
1559 | + |
1560 | +/* |
1561 | + * It shows all hosts in ACL lists |
1562 | + */ |
1563 | + |
1564 | +void show_acl_lists(void) { |
1565 | + struct ip_acl *ip_acl_curr = ip_acl_head; |
1566 | + struct dns_acl *dns_acl_curr = dns_acl_head; |
1567 | + |
1568 | + while (ip_acl_curr != NULL) { |
1569 | + printf(" IP ACL: %s/%u %u\n", inet_ntoa(ip_acl_curr->addr), prefix_from_mask(ip_acl_curr->mask), ip_acl_curr->addr.s_addr); |
1570 | + ip_acl_curr = ip_acl_curr->next; |
1571 | + } |
1572 | + |
1573 | + while (dns_acl_curr != NULL) { |
1574 | + printf("DNS ACL: %s\n", dns_acl_curr->domain); |
1575 | + dns_acl_curr = dns_acl_curr->next; |
1576 | + } |
1577 | +} |
1578 | |
1579 | === modified file 'src/check_nrpe.c' (properties changed: -x to +x) |
1580 | --- src/check_nrpe.c 2008-08-06 20:33:57 +0000 |
1581 | +++ src/check_nrpe.c 2013-02-02 23:23:20 +0000 |
1582 | @@ -1,462 +1,462 @@ |
1583 | -/******************************************************************************************** |
1584 | - * |
1585 | - * CHECK_NRPE.C - NRPE Plugin For Nagios |
1586 | - * Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org) |
1587 | - * License: GPL |
1588 | - * |
1589 | - * Last Modified: 03-10-2008 |
1590 | - * |
1591 | - * Command line: CHECK_NRPE -H <host_address> [-p port] [-c command] [-to to_sec] |
1592 | - * |
1593 | - * Description: |
1594 | - * |
1595 | - * This plugin will attempt to connect to the NRPE daemon on the specified server and port. |
1596 | - * The daemon will attempt to run the command defined as [command]. Program output and |
1597 | - * return code are sent back from the daemon and displayed as this plugin's own output and |
1598 | - * return code. |
1599 | - * |
1600 | - ********************************************************************************************/ |
1601 | - |
1602 | -#include "../include/common.h" |
1603 | -#include "../include/config.h" |
1604 | -#include "../include/utils.h" |
1605 | - |
1606 | - |
1607 | -#define DEFAULT_NRPE_COMMAND "_NRPE_CHECK" /* check version of NRPE daemon */ |
1608 | - |
1609 | -int server_port=DEFAULT_SERVER_PORT; |
1610 | -char *server_name=NULL; |
1611 | -char *command_name=NULL; |
1612 | -int socket_timeout=DEFAULT_SOCKET_TIMEOUT; |
1613 | -int timeout_return_code=STATE_CRITICAL; |
1614 | -int sd; |
1615 | - |
1616 | -char query[MAX_INPUT_BUFFER]=""; |
1617 | - |
1618 | -int show_help=FALSE; |
1619 | -int show_license=FALSE; |
1620 | -int show_version=FALSE; |
1621 | - |
1622 | -#ifdef HAVE_SSL |
1623 | -SSL_METHOD *meth; |
1624 | -SSL_CTX *ctx; |
1625 | -SSL *ssl; |
1626 | -int use_ssl=TRUE; |
1627 | -#else |
1628 | -int use_ssl=FALSE; |
1629 | -#endif |
1630 | - |
1631 | - |
1632 | -int process_arguments(int,char **); |
1633 | -void alarm_handler(int); |
1634 | -int graceful_close(int,int); |
1635 | - |
1636 | - |
1637 | - |
1638 | - |
1639 | -int main(int argc, char **argv){ |
1640 | - u_int32_t packet_crc32; |
1641 | - u_int32_t calculated_crc32; |
1642 | - int16_t result; |
1643 | - int rc; |
1644 | - packet send_packet; |
1645 | - packet receive_packet; |
1646 | - int bytes_to_send; |
1647 | - int bytes_to_recv; |
1648 | - |
1649 | - result=process_arguments(argc,argv); |
1650 | - |
1651 | - if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){ |
1652 | - |
1653 | - if(result!=OK) |
1654 | - printf("Incorrect command line arguments supplied\n"); |
1655 | - printf("\n"); |
1656 | - printf("NRPE Plugin for Nagios\n"); |
1657 | - printf("Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)\n"); |
1658 | - printf("Version: %s\n",PROGRAM_VERSION); |
1659 | - printf("Last Modified: %s\n",MODIFICATION_DATE); |
1660 | - printf("License: GPL v2 with exemptions (-l for more info)\n"); |
1661 | -#ifdef HAVE_SSL |
1662 | - printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n"); |
1663 | -#endif |
1664 | - printf("\n"); |
1665 | - } |
1666 | - |
1667 | - if(result!=OK || show_help==TRUE){ |
1668 | - |
1669 | - printf("Usage: check_nrpe -H <host> [-n] [-u] [-p <port>] [-t <timeout>] [-c <command>] [-a <arglist...>]\n"); |
1670 | - printf("\n"); |
1671 | - printf("Options:\n"); |
1672 | - printf(" -n = Do no use SSL\n"); |
1673 | - printf(" -u = Make socket timeouts return an UNKNOWN state instead of CRITICAL\n"); |
1674 | - printf(" <host> = The address of the host running the NRPE daemon\n"); |
1675 | - printf(" [port] = The port on which the daemon is running (default=%d)\n",DEFAULT_SERVER_PORT); |
1676 | - printf(" [timeout] = Number of seconds before connection times out (default=%d)\n",DEFAULT_SOCKET_TIMEOUT); |
1677 | - printf(" [command] = The name of the command that the remote daemon should run\n"); |
1678 | - printf(" [arglist] = Optional arguments that should be passed to the command. Multiple\n"); |
1679 | - printf(" arguments should be separated by a space. If provided, this must be\n"); |
1680 | - printf(" the last option supplied on the command line.\n"); |
1681 | - printf("\n"); |
1682 | - printf("Note:\n"); |
1683 | - printf("This plugin requires that you have the NRPE daemon running on the remote host.\n"); |
1684 | - printf("You must also have configured the daemon to associate a specific plugin command\n"); |
1685 | - printf("with the [command] option you are specifying here. Upon receipt of the\n"); |
1686 | - printf("[command] argument, the NRPE daemon will run the appropriate plugin command and\n"); |
1687 | - printf("send the plugin output and return code back to *this* plugin. This allows you\n"); |
1688 | - printf("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n"); |
1689 | - printf("the plugin is being run locally.\n"); |
1690 | - printf("\n"); |
1691 | - } |
1692 | - |
1693 | - if(show_license==TRUE) |
1694 | - display_license(); |
1695 | - |
1696 | - if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE) |
1697 | - exit(STATE_UNKNOWN); |
1698 | - |
1699 | - |
1700 | - /* generate the CRC 32 table */ |
1701 | - generate_crc32_table(); |
1702 | - |
1703 | -#ifdef HAVE_SSL |
1704 | - /* initialize SSL */ |
1705 | - if(use_ssl==TRUE){ |
1706 | - SSL_library_init(); |
1707 | - SSLeay_add_ssl_algorithms(); |
1708 | - meth=SSLv23_client_method(); |
1709 | - SSL_load_error_strings(); |
1710 | - if((ctx=SSL_CTX_new(meth))==NULL){ |
1711 | - printf("CHECK_NRPE: Error - could not create SSL context.\n"); |
1712 | - exit(STATE_CRITICAL); |
1713 | - } |
1714 | - |
1715 | - /* ADDED 01/19/2004 */ |
1716 | - /* use only TLSv1 protocol */ |
1717 | - SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); |
1718 | - } |
1719 | -#endif |
1720 | - |
1721 | - /* initialize alarm signal handling */ |
1722 | - signal(SIGALRM,alarm_handler); |
1723 | - |
1724 | - /* set socket timeout */ |
1725 | - alarm(socket_timeout); |
1726 | - |
1727 | - /* try to connect to the host at the given port number */ |
1728 | - result=my_tcp_connect(server_name,server_port,&sd); |
1729 | - |
1730 | -#ifdef HAVE_SSL |
1731 | - /* do SSL handshake */ |
1732 | - if(result==STATE_OK && use_ssl==TRUE){ |
1733 | - if((ssl=SSL_new(ctx))!=NULL){ |
1734 | - SSL_CTX_set_cipher_list(ctx,"ADH"); |
1735 | - SSL_set_fd(ssl,sd); |
1736 | - if((rc=SSL_connect(ssl))!=1){ |
1737 | - printf("CHECK_NRPE: Error - Could not complete SSL handshake.\n"); |
1738 | -#ifdef DEBUG |
1739 | - printf("SSL_connect=%d\n",rc); |
1740 | - /* |
1741 | - rc=SSL_get_error(ssl,rc); |
1742 | - printf("SSL_get_error=%d\n",rc); |
1743 | - printf("ERR_get_error=%lu\n",ERR_get_error()); |
1744 | - printf("%s\n",ERR_error_string(rc,NULL)); |
1745 | - */ |
1746 | - ERR_print_errors_fp(stdout); |
1747 | -#endif |
1748 | - result=STATE_CRITICAL; |
1749 | - } |
1750 | - } |
1751 | - else{ |
1752 | - printf("CHECK_NRPE: Error - Could not create SSL connection structure.\n"); |
1753 | - result=STATE_CRITICAL; |
1754 | - } |
1755 | - |
1756 | - /* bail if we had errors */ |
1757 | - if(result!=STATE_OK){ |
1758 | - SSL_CTX_free(ctx); |
1759 | - close(sd); |
1760 | - exit(result); |
1761 | - } |
1762 | - } |
1763 | -#endif |
1764 | - |
1765 | - /* we're connected and ready to go */ |
1766 | - if(result==STATE_OK){ |
1767 | - |
1768 | - /* clear the packet buffer */ |
1769 | - bzero(&send_packet,sizeof(send_packet)); |
1770 | - |
1771 | - /* fill the packet with semi-random data */ |
1772 | - randomize_buffer((char *)&send_packet,sizeof(send_packet)); |
1773 | - |
1774 | - /* initialize packet data */ |
1775 | - send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2); |
1776 | - send_packet.packet_type=(int16_t)htons(QUERY_PACKET); |
1777 | - strncpy(&send_packet.buffer[0],query,MAX_PACKETBUFFER_LENGTH); |
1778 | - send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; |
1779 | - |
1780 | - /* calculate the crc 32 value of the packet */ |
1781 | - send_packet.crc32_value=(u_int32_t)0L; |
1782 | - calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet)); |
1783 | - send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32); |
1784 | - |
1785 | - |
1786 | - /***** ENCRYPT REQUEST *****/ |
1787 | - |
1788 | - |
1789 | - /* send the packet */ |
1790 | - bytes_to_send=sizeof(send_packet); |
1791 | - if(use_ssl==FALSE) |
1792 | - rc=sendall(sd,(char *)&send_packet,&bytes_to_send); |
1793 | -#ifdef HAVE_SSL |
1794 | - else{ |
1795 | - rc=SSL_write(ssl,&send_packet,bytes_to_send); |
1796 | - if(rc<0) |
1797 | - rc=-1; |
1798 | - } |
1799 | -#endif |
1800 | - if(rc==-1){ |
1801 | - printf("CHECK_NRPE: Error sending query to host.\n"); |
1802 | - close(sd); |
1803 | - return STATE_UNKNOWN; |
1804 | - } |
1805 | - |
1806 | - /* wait for the response packet */ |
1807 | - bytes_to_recv=sizeof(receive_packet); |
1808 | - if(use_ssl==FALSE) |
1809 | - rc=recvall(sd,(char *)&receive_packet,&bytes_to_recv,socket_timeout); |
1810 | -#ifdef HAVE_SSL |
1811 | - else |
1812 | - rc=SSL_read(ssl,&receive_packet,bytes_to_recv); |
1813 | -#endif |
1814 | - |
1815 | - /* reset timeout */ |
1816 | - alarm(0); |
1817 | - |
1818 | - /* close the connection */ |
1819 | -#ifdef HAVE_SSL |
1820 | - if(use_ssl==TRUE){ |
1821 | - SSL_shutdown(ssl); |
1822 | - SSL_free(ssl); |
1823 | - SSL_CTX_free(ctx); |
1824 | - } |
1825 | -#endif |
1826 | - graceful_close(sd,1000); |
1827 | - |
1828 | - /* recv() error */ |
1829 | - if(rc<0){ |
1830 | - printf("CHECK_NRPE: Error receiving data from daemon.\n"); |
1831 | - return STATE_UNKNOWN; |
1832 | - } |
1833 | - |
1834 | - /* server disconnected */ |
1835 | - else if(rc==0){ |
1836 | - printf("CHECK_NRPE: Received 0 bytes from daemon. Check the remote server logs for error messages.\n"); |
1837 | - return STATE_UNKNOWN; |
1838 | - } |
1839 | - |
1840 | - /* receive underflow */ |
1841 | - else if(bytes_to_recv<sizeof(receive_packet)){ |
1842 | - printf("CHECK_NRPE: Receive underflow - only %d bytes received (%d expected).\n",bytes_to_recv,sizeof(receive_packet)); |
1843 | - return STATE_UNKNOWN; |
1844 | - } |
1845 | - |
1846 | - |
1847 | - /***** DECRYPT RESPONSE *****/ |
1848 | - |
1849 | - |
1850 | - /* check the crc 32 value */ |
1851 | - packet_crc32=ntohl(receive_packet.crc32_value); |
1852 | - receive_packet.crc32_value=0L; |
1853 | - calculated_crc32=calculate_crc32((char *)&receive_packet,sizeof(receive_packet)); |
1854 | - if(packet_crc32!=calculated_crc32){ |
1855 | - printf("CHECK_NRPE: Response packet had invalid CRC32.\n"); |
1856 | - close(sd); |
1857 | - return STATE_UNKNOWN; |
1858 | - } |
1859 | - |
1860 | - /* check packet version */ |
1861 | - if(ntohs(receive_packet.packet_version)!=NRPE_PACKET_VERSION_2){ |
1862 | - printf("CHECK_NRPE: Invalid packet version received from server.\n"); |
1863 | - close(sd); |
1864 | - return STATE_UNKNOWN; |
1865 | - } |
1866 | - |
1867 | - /* check packet type */ |
1868 | - if(ntohs(receive_packet.packet_type)!=RESPONSE_PACKET){ |
1869 | - printf("CHECK_NRPE: Invalid packet type received from server.\n"); |
1870 | - close(sd); |
1871 | - return STATE_UNKNOWN; |
1872 | - } |
1873 | - |
1874 | - /* get the return code from the remote plugin */ |
1875 | - result=(int16_t)ntohs(receive_packet.result_code); |
1876 | - |
1877 | - /* print the output returned by the daemon */ |
1878 | - receive_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; |
1879 | - if(!strcmp(receive_packet.buffer,"")) |
1880 | - printf("CHECK_NRPE: No output returned from daemon.\n"); |
1881 | - else |
1882 | - printf("%s\n",receive_packet.buffer); |
1883 | - } |
1884 | - |
1885 | - /* reset the alarm */ |
1886 | - else |
1887 | - alarm(0); |
1888 | - |
1889 | - return result; |
1890 | - } |
1891 | - |
1892 | - |
1893 | - |
1894 | -/* process command line arguments */ |
1895 | -int process_arguments(int argc, char **argv){ |
1896 | - char optchars[MAX_INPUT_BUFFER]; |
1897 | - int argindex=0; |
1898 | - int c=1; |
1899 | - int i=1; |
1900 | - |
1901 | -#ifdef HAVE_GETOPT_LONG |
1902 | - int option_index=0; |
1903 | - static struct option long_options[]={ |
1904 | - {"host", required_argument, 0, 'H'}, |
1905 | - {"command", required_argument, 0, 'c'}, |
1906 | - {"args", required_argument, 0, 'a'}, |
1907 | - {"no-ssl", no_argument, 0, 'n'}, |
1908 | - {"unknown-timeout", no_argument, 0, 'u'}, |
1909 | - {"timeout", required_argument, 0, 't'}, |
1910 | - {"port", required_argument, 0, 'p'}, |
1911 | - {"help", no_argument, 0, 'h'}, |
1912 | - {"license", no_argument, 0, 'l'}, |
1913 | - {0, 0, 0, 0} |
1914 | - }; |
1915 | -#endif |
1916 | - |
1917 | - /* no options were supplied */ |
1918 | - if(argc<2) |
1919 | - return ERROR; |
1920 | - |
1921 | - snprintf(optchars,MAX_INPUT_BUFFER,"H:c:a:t:p:nuhl"); |
1922 | - |
1923 | - while(1){ |
1924 | -#ifdef HAVE_GETOPT_LONG |
1925 | - c=getopt_long(argc,argv,optchars,long_options,&option_index); |
1926 | -#else |
1927 | - c=getopt(argc,argv,optchars); |
1928 | -#endif |
1929 | - if(c==-1 || c==EOF) |
1930 | - break; |
1931 | - |
1932 | - /* process all arguments */ |
1933 | - switch(c){ |
1934 | - |
1935 | - case '?': |
1936 | - case 'h': |
1937 | - show_help=TRUE; |
1938 | - break; |
1939 | - case 'V': |
1940 | - show_version=TRUE; |
1941 | - break; |
1942 | - case 'l': |
1943 | - show_license=TRUE; |
1944 | - break; |
1945 | - case 't': |
1946 | - socket_timeout=atoi(optarg); |
1947 | - if(socket_timeout<=0) |
1948 | - return ERROR; |
1949 | - break; |
1950 | - case 'p': |
1951 | - server_port=atoi(optarg); |
1952 | - if(server_port<=0) |
1953 | - return ERROR; |
1954 | - break; |
1955 | - case 'H': |
1956 | - server_name=strdup(optarg); |
1957 | - break; |
1958 | - case 'c': |
1959 | - command_name=strdup(optarg); |
1960 | - break; |
1961 | - case 'a': |
1962 | - argindex=optind; |
1963 | - break; |
1964 | - case 'n': |
1965 | - use_ssl=FALSE; |
1966 | - break; |
1967 | - case 'u': |
1968 | - timeout_return_code=STATE_UNKNOWN; |
1969 | - break; |
1970 | - default: |
1971 | - return ERROR; |
1972 | - break; |
1973 | - } |
1974 | - } |
1975 | - |
1976 | - /* determine (base) command query */ |
1977 | - snprintf(query,sizeof(query),"%s",(command_name==NULL)?DEFAULT_NRPE_COMMAND:command_name); |
1978 | - query[sizeof(query)-1]='\x0'; |
1979 | - |
1980 | - /* get the command args */ |
1981 | - if(argindex>0){ |
1982 | - |
1983 | - for(c=argindex-1;c<argc;c++){ |
1984 | - |
1985 | - i=sizeof(query)-strlen(query)-2; |
1986 | - if(i<=0) |
1987 | - break; |
1988 | - |
1989 | - strcat(query,"!"); |
1990 | - strncat(query,argv[c],i); |
1991 | - query[sizeof(query)-1]='\x0'; |
1992 | - } |
1993 | - } |
1994 | - |
1995 | - /* make sure required args were supplied */ |
1996 | - if(server_name==NULL && show_help==FALSE && show_version==FALSE && show_license==FALSE) |
1997 | - return ERROR; |
1998 | - |
1999 | - |
2000 | - return OK; |
2001 | - } |
2002 | - |
2003 | - |
2004 | - |
2005 | -void alarm_handler(int sig){ |
2006 | - |
2007 | - printf("CHECK_NRPE: Socket timeout after %d seconds.\n",socket_timeout); |
2008 | - |
2009 | - exit(timeout_return_code); |
2010 | - } |
2011 | - |
2012 | - |
2013 | -/* submitted by Mark Plaksin 08/31/2006 */ |
2014 | -int graceful_close(int sd, int timeout){ |
2015 | - fd_set in; |
2016 | - struct timeval tv; |
2017 | - char buf[1000]; |
2018 | - |
2019 | - /* send FIN packet */ |
2020 | - shutdown(sd,SHUT_WR); |
2021 | - for(;;){ |
2022 | - |
2023 | - FD_ZERO(&in); |
2024 | - FD_SET(sd,&in); |
2025 | - tv.tv_sec=timeout/1000; |
2026 | - tv.tv_usec=(timeout % 1000)*1000; |
2027 | - |
2028 | - /* timeout or error */ |
2029 | - if(1!=select(sd+1,&in,NULL,NULL,&tv)) |
2030 | - break; |
2031 | - |
2032 | - /* no more data (FIN or RST) */ |
2033 | - if(0>=recv(sd,buf,sizeof(buf),0)) |
2034 | - break; |
2035 | - } |
2036 | - |
2037 | -#ifdef HAVE_CLOSESOCKET |
2038 | - closesocket(sd); |
2039 | -#else |
2040 | - close(sd); |
2041 | -#endif |
2042 | - |
2043 | - return OK; |
2044 | - } |
2045 | +/******************************************************************************************** |
2046 | + * |
2047 | + * CHECK_NRPE.C - NRPE Plugin For Nagios |
2048 | + * Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org) |
2049 | + * License: GPL |
2050 | + * |
2051 | + * Last Modified: 11-11-2011 |
2052 | + * |
2053 | + * Command line: CHECK_NRPE -H <host_address> [-p port] [-c command] [-to to_sec] |
2054 | + * |
2055 | + * Description: |
2056 | + * |
2057 | + * This plugin will attempt to connect to the NRPE daemon on the specified server and port. |
2058 | + * The daemon will attempt to run the command defined as [command]. Program output and |
2059 | + * return code are sent back from the daemon and displayed as this plugin's own output and |
2060 | + * return code. |
2061 | + * |
2062 | + ********************************************************************************************/ |
2063 | + |
2064 | +#include "../include/common.h" |
2065 | +#include "../include/config.h" |
2066 | +#include "../include/utils.h" |
2067 | + |
2068 | + |
2069 | +#define DEFAULT_NRPE_COMMAND "_NRPE_CHECK" /* check version of NRPE daemon */ |
2070 | + |
2071 | +int server_port=DEFAULT_SERVER_PORT; |
2072 | +char *server_name=NULL; |
2073 | +char *command_name=NULL; |
2074 | +int socket_timeout=DEFAULT_SOCKET_TIMEOUT; |
2075 | +int timeout_return_code=STATE_CRITICAL; |
2076 | +int sd; |
2077 | + |
2078 | +char query[MAX_INPUT_BUFFER]=""; |
2079 | + |
2080 | +int show_help=FALSE; |
2081 | +int show_license=FALSE; |
2082 | +int show_version=FALSE; |
2083 | + |
2084 | +#ifdef HAVE_SSL |
2085 | +SSL_METHOD *meth; |
2086 | +SSL_CTX *ctx; |
2087 | +SSL *ssl; |
2088 | +int use_ssl=TRUE; |
2089 | +#else |
2090 | +int use_ssl=FALSE; |
2091 | +#endif |
2092 | + |
2093 | + |
2094 | +int process_arguments(int,char **); |
2095 | +void alarm_handler(int); |
2096 | +int graceful_close(int,int); |
2097 | + |
2098 | + |
2099 | + |
2100 | + |
2101 | +int main(int argc, char **argv){ |
2102 | + u_int32_t packet_crc32; |
2103 | + u_int32_t calculated_crc32; |
2104 | + int16_t result; |
2105 | + int rc; |
2106 | + packet send_packet; |
2107 | + packet receive_packet; |
2108 | + int bytes_to_send; |
2109 | + int bytes_to_recv; |
2110 | + |
2111 | + result=process_arguments(argc,argv); |
2112 | + |
2113 | + if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){ |
2114 | + |
2115 | + if(result!=OK) |
2116 | + printf("Incorrect command line arguments supplied\n"); |
2117 | + printf("\n"); |
2118 | + printf("NRPE Plugin for Nagios\n"); |
2119 | + printf("Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)\n"); |
2120 | + printf("Version: %s\n",PROGRAM_VERSION); |
2121 | + printf("Last Modified: %s\n",MODIFICATION_DATE); |
2122 | + printf("License: GPL v2 with exemptions (-l for more info)\n"); |
2123 | +#ifdef HAVE_SSL |
2124 | + printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n"); |
2125 | +#endif |
2126 | + printf("\n"); |
2127 | + } |
2128 | + |
2129 | + if(result!=OK || show_help==TRUE){ |
2130 | + |
2131 | + printf("Usage: check_nrpe -H <host> [-n] [-u] [-p <port>] [-t <timeout>] [-c <command>] [-a <arglist...>]\n"); |
2132 | + printf("\n"); |
2133 | + printf("Options:\n"); |
2134 | + printf(" -n = Do no use SSL\n"); |
2135 | + printf(" -u = Make socket timeouts return an UNKNOWN state instead of CRITICAL\n"); |
2136 | + printf(" <host> = The address of the host running the NRPE daemon\n"); |
2137 | + printf(" [port] = The port on which the daemon is running (default=%d)\n",DEFAULT_SERVER_PORT); |
2138 | + printf(" [timeout] = Number of seconds before connection times out (default=%d)\n",DEFAULT_SOCKET_TIMEOUT); |
2139 | + printf(" [command] = The name of the command that the remote daemon should run\n"); |
2140 | + printf(" [arglist] = Optional arguments that should be passed to the command. Multiple\n"); |
2141 | + printf(" arguments should be separated by a space. If provided, this must be\n"); |
2142 | + printf(" the last option supplied on the command line.\n"); |
2143 | + printf("\n"); |
2144 | + printf("Note:\n"); |
2145 | + printf("This plugin requires that you have the NRPE daemon running on the remote host.\n"); |
2146 | + printf("You must also have configured the daemon to associate a specific plugin command\n"); |
2147 | + printf("with the [command] option you are specifying here. Upon receipt of the\n"); |
2148 | + printf("[command] argument, the NRPE daemon will run the appropriate plugin command and\n"); |
2149 | + printf("send the plugin output and return code back to *this* plugin. This allows you\n"); |
2150 | + printf("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n"); |
2151 | + printf("the plugin is being run locally.\n"); |
2152 | + printf("\n"); |
2153 | + } |
2154 | + |
2155 | + if(show_license==TRUE) |
2156 | + display_license(); |
2157 | + |
2158 | + if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE) |
2159 | + exit(STATE_UNKNOWN); |
2160 | + |
2161 | + |
2162 | + /* generate the CRC 32 table */ |
2163 | + generate_crc32_table(); |
2164 | + |
2165 | +#ifdef HAVE_SSL |
2166 | + /* initialize SSL */ |
2167 | + if(use_ssl==TRUE){ |
2168 | + SSL_library_init(); |
2169 | + SSLeay_add_ssl_algorithms(); |
2170 | + meth=SSLv23_client_method(); |
2171 | + SSL_load_error_strings(); |
2172 | + if((ctx=SSL_CTX_new(meth))==NULL){ |
2173 | + printf("CHECK_NRPE: Error - could not create SSL context.\n"); |
2174 | + exit(STATE_CRITICAL); |
2175 | + } |
2176 | + |
2177 | + /* ADDED 01/19/2004 */ |
2178 | + /* use only TLSv1 protocol */ |
2179 | + SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); |
2180 | + } |
2181 | +#endif |
2182 | + |
2183 | + /* initialize alarm signal handling */ |
2184 | + signal(SIGALRM,alarm_handler); |
2185 | + |
2186 | + /* set socket timeout */ |
2187 | + alarm(socket_timeout); |
2188 | + |
2189 | + /* try to connect to the host at the given port number */ |
2190 | + result=my_tcp_connect(server_name,server_port,&sd); |
2191 | + |
2192 | +#ifdef HAVE_SSL |
2193 | + /* do SSL handshake */ |
2194 | + if(result==STATE_OK && use_ssl==TRUE){ |
2195 | + if((ssl=SSL_new(ctx))!=NULL){ |
2196 | + SSL_CTX_set_cipher_list(ctx,"ADH"); |
2197 | + SSL_set_fd(ssl,sd); |
2198 | + if((rc=SSL_connect(ssl))!=1){ |
2199 | + printf("CHECK_NRPE: Error - Could not complete SSL handshake.\n"); |
2200 | +#ifdef DEBUG |
2201 | + printf("SSL_connect=%d\n",rc); |
2202 | + /* |
2203 | + rc=SSL_get_error(ssl,rc); |
2204 | + printf("SSL_get_error=%d\n",rc); |
2205 | + printf("ERR_get_error=%lu\n",ERR_get_error()); |
2206 | + printf("%s\n",ERR_error_string(rc,NULL)); |
2207 | + */ |
2208 | + ERR_print_errors_fp(stdout); |
2209 | +#endif |
2210 | + result=STATE_CRITICAL; |
2211 | + } |
2212 | + } |
2213 | + else{ |
2214 | + printf("CHECK_NRPE: Error - Could not create SSL connection structure.\n"); |
2215 | + result=STATE_CRITICAL; |
2216 | + } |
2217 | + |
2218 | + /* bail if we had errors */ |
2219 | + if(result!=STATE_OK){ |
2220 | + SSL_CTX_free(ctx); |
2221 | + close(sd); |
2222 | + exit(result); |
2223 | + } |
2224 | + } |
2225 | +#endif |
2226 | + |
2227 | + /* we're connected and ready to go */ |
2228 | + if(result==STATE_OK){ |
2229 | + |
2230 | + /* clear the packet buffer */ |
2231 | + bzero(&send_packet,sizeof(send_packet)); |
2232 | + |
2233 | + /* fill the packet with semi-random data */ |
2234 | + randomize_buffer((char *)&send_packet,sizeof(send_packet)); |
2235 | + |
2236 | + /* initialize packet data */ |
2237 | + send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2); |
2238 | + send_packet.packet_type=(int16_t)htons(QUERY_PACKET); |
2239 | + strncpy(&send_packet.buffer[0],query,MAX_PACKETBUFFER_LENGTH); |
2240 | + send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; |
2241 | + |
2242 | + /* calculate the crc 32 value of the packet */ |
2243 | + send_packet.crc32_value=(u_int32_t)0L; |
2244 | + calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet)); |
2245 | + send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32); |
2246 | + |
2247 | + |
2248 | + /***** ENCRYPT REQUEST *****/ |
2249 | + |
2250 | + |
2251 | + /* send the packet */ |
2252 | + bytes_to_send=sizeof(send_packet); |
2253 | + if(use_ssl==FALSE) |
2254 | + rc=sendall(sd,(char *)&send_packet,&bytes_to_send); |
2255 | +#ifdef HAVE_SSL |
2256 | + else{ |
2257 | + rc=SSL_write(ssl,&send_packet,bytes_to_send); |
2258 | + if(rc<0) |
2259 | + rc=-1; |
2260 | + } |
2261 | +#endif |
2262 | + if(rc==-1){ |
2263 | + printf("CHECK_NRPE: Error sending query to host.\n"); |
2264 | + close(sd); |
2265 | + return STATE_UNKNOWN; |
2266 | + } |
2267 | + |
2268 | + /* wait for the response packet */ |
2269 | + bytes_to_recv=sizeof(receive_packet); |
2270 | + if(use_ssl==FALSE) |
2271 | + rc=recvall(sd,(char *)&receive_packet,&bytes_to_recv,socket_timeout); |
2272 | +#ifdef HAVE_SSL |
2273 | + else |
2274 | + rc=SSL_read(ssl,&receive_packet,bytes_to_recv); |
2275 | +#endif |
2276 | + |
2277 | + /* reset timeout */ |
2278 | + alarm(0); |
2279 | + |
2280 | + /* close the connection */ |
2281 | +#ifdef HAVE_SSL |
2282 | + if(use_ssl==TRUE){ |
2283 | + SSL_shutdown(ssl); |
2284 | + SSL_free(ssl); |
2285 | + SSL_CTX_free(ctx); |
2286 | + } |
2287 | +#endif |
2288 | + graceful_close(sd,1000); |
2289 | + |
2290 | + /* recv() error */ |
2291 | + if(rc<0){ |
2292 | + printf("CHECK_NRPE: Error receiving data from daemon.\n"); |
2293 | + return STATE_UNKNOWN; |
2294 | + } |
2295 | + |
2296 | + /* server disconnected */ |
2297 | + else if(rc==0){ |
2298 | + printf("CHECK_NRPE: Received 0 bytes from daemon. Check the remote server logs for error messages.\n"); |
2299 | + return STATE_UNKNOWN; |
2300 | + } |
2301 | + |
2302 | + /* receive underflow */ |
2303 | + else if(bytes_to_recv<sizeof(receive_packet)){ |
2304 | + printf("CHECK_NRPE: Receive underflow - only %d bytes received (%d expected).\n",bytes_to_recv,sizeof(receive_packet)); |
2305 | + return STATE_UNKNOWN; |
2306 | + } |
2307 | + |
2308 | + |
2309 | + /***** DECRYPT RESPONSE *****/ |
2310 | + |
2311 | + |
2312 | + /* check the crc 32 value */ |
2313 | + packet_crc32=ntohl(receive_packet.crc32_value); |
2314 | + receive_packet.crc32_value=0L; |
2315 | + calculated_crc32=calculate_crc32((char *)&receive_packet,sizeof(receive_packet)); |
2316 | + if(packet_crc32!=calculated_crc32){ |
2317 | + printf("CHECK_NRPE: Response packet had invalid CRC32.\n"); |
2318 | + close(sd); |
2319 | + return STATE_UNKNOWN; |
2320 | + } |
2321 | + |
2322 | + /* check packet version */ |
2323 | + if(ntohs(receive_packet.packet_version)!=NRPE_PACKET_VERSION_2){ |
2324 | + printf("CHECK_NRPE: Invalid packet version received from server.\n"); |
2325 | + close(sd); |
2326 | + return STATE_UNKNOWN; |
2327 | + } |
2328 | + |
2329 | + /* check packet type */ |
2330 | + if(ntohs(receive_packet.packet_type)!=RESPONSE_PACKET){ |
2331 | + printf("CHECK_NRPE: Invalid packet type received from server.\n"); |
2332 | + close(sd); |
2333 | + return STATE_UNKNOWN; |
2334 | + } |
2335 | + |
2336 | + /* get the return code from the remote plugin */ |
2337 | + result=(int16_t)ntohs(receive_packet.result_code); |
2338 | + |
2339 | + /* print the output returned by the daemon */ |
2340 | + receive_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; |
2341 | + if(!strcmp(receive_packet.buffer,"")) |
2342 | + printf("CHECK_NRPE: No output returned from daemon.\n"); |
2343 | + else |
2344 | + printf("%s\n",receive_packet.buffer); |
2345 | + } |
2346 | + |
2347 | + /* reset the alarm */ |
2348 | + else |
2349 | + alarm(0); |
2350 | + |
2351 | + return result; |
2352 | + } |
2353 | + |
2354 | + |
2355 | + |
2356 | +/* process command line arguments */ |
2357 | +int process_arguments(int argc, char **argv){ |
2358 | + char optchars[MAX_INPUT_BUFFER]; |
2359 | + int argindex=0; |
2360 | + int c=1; |
2361 | + int i=1; |
2362 | + |
2363 | +#ifdef HAVE_GETOPT_LONG |
2364 | + int option_index=0; |
2365 | + static struct option long_options[]={ |
2366 | + {"host", required_argument, 0, 'H'}, |
2367 | + {"command", required_argument, 0, 'c'}, |
2368 | + {"args", required_argument, 0, 'a'}, |
2369 | + {"no-ssl", no_argument, 0, 'n'}, |
2370 | + {"unknown-timeout", no_argument, 0, 'u'}, |
2371 | + {"timeout", required_argument, 0, 't'}, |
2372 | + {"port", required_argument, 0, 'p'}, |
2373 | + {"help", no_argument, 0, 'h'}, |
2374 | + {"license", no_argument, 0, 'l'}, |
2375 | + {0, 0, 0, 0} |
2376 | + }; |
2377 | +#endif |
2378 | + |
2379 | + /* no options were supplied */ |
2380 | + if(argc<2) |
2381 | + return ERROR; |
2382 | + |
2383 | + snprintf(optchars,MAX_INPUT_BUFFER,"H:c:a:t:p:nuhl"); |
2384 | + |
2385 | + while(1){ |
2386 | +#ifdef HAVE_GETOPT_LONG |
2387 | + c=getopt_long(argc,argv,optchars,long_options,&option_index); |
2388 | +#else |
2389 | + c=getopt(argc,argv,optchars); |
2390 | +#endif |
2391 | + if(c==-1 || c==EOF) |
2392 | + break; |
2393 | + |
2394 | + /* process all arguments */ |
2395 | + switch(c){ |
2396 | + |
2397 | + case '?': |
2398 | + case 'h': |
2399 | + show_help=TRUE; |
2400 | + break; |
2401 | + case 'V': |
2402 | + show_version=TRUE; |
2403 | + break; |
2404 | + case 'l': |
2405 | + show_license=TRUE; |
2406 | + break; |
2407 | + case 't': |
2408 | + socket_timeout=atoi(optarg); |
2409 | + if(socket_timeout<=0) |
2410 | + return ERROR; |
2411 | + break; |
2412 | + case 'p': |
2413 | + server_port=atoi(optarg); |
2414 | + if(server_port<=0) |
2415 | + return ERROR; |
2416 | + break; |
2417 | + case 'H': |
2418 | + server_name=strdup(optarg); |
2419 | + break; |
2420 | + case 'c': |
2421 | + command_name=strdup(optarg); |
2422 | + break; |
2423 | + case 'a': |
2424 | + argindex=optind; |
2425 | + break; |
2426 | + case 'n': |
2427 | + use_ssl=FALSE; |
2428 | + break; |
2429 | + case 'u': |
2430 | + timeout_return_code=STATE_UNKNOWN; |
2431 | + break; |
2432 | + default: |
2433 | + return ERROR; |
2434 | + break; |
2435 | + } |
2436 | + } |
2437 | + |
2438 | + /* determine (base) command query */ |
2439 | + snprintf(query,sizeof(query),"%s",(command_name==NULL)?DEFAULT_NRPE_COMMAND:command_name); |
2440 | + query[sizeof(query)-1]='\x0'; |
2441 | + |
2442 | + /* get the command args */ |
2443 | + if(argindex>0){ |
2444 | + |
2445 | + for(c=argindex-1;c<argc;c++){ |
2446 | + |
2447 | + i=sizeof(query)-strlen(query)-2; |
2448 | + if(i<=0) |
2449 | + break; |
2450 | + |
2451 | + strcat(query,"!"); |
2452 | + strncat(query,argv[c],i); |
2453 | + query[sizeof(query)-1]='\x0'; |
2454 | + } |
2455 | + } |
2456 | + |
2457 | + /* make sure required args were supplied */ |
2458 | + if(server_name==NULL && show_help==FALSE && show_version==FALSE && show_license==FALSE) |
2459 | + return ERROR; |
2460 | + |
2461 | + |
2462 | + return OK; |
2463 | + } |
2464 | + |
2465 | + |
2466 | + |
2467 | +void alarm_handler(int sig){ |
2468 | + |
2469 | + printf("CHECK_NRPE: Socket timeout after %d seconds.\n",socket_timeout); |
2470 | + |
2471 | + exit(timeout_return_code); |
2472 | + } |
2473 | + |
2474 | + |
2475 | +/* submitted by Mark Plaksin 08/31/2006 */ |
2476 | +int graceful_close(int sd, int timeout){ |
2477 | + fd_set in; |
2478 | + struct timeval tv; |
2479 | + char buf[1000]; |
2480 | + |
2481 | + /* send FIN packet */ |
2482 | + shutdown(sd,SHUT_WR); |
2483 | + for(;;){ |
2484 | + |
2485 | + FD_ZERO(&in); |
2486 | + FD_SET(sd,&in); |
2487 | + tv.tv_sec=timeout/1000; |
2488 | + tv.tv_usec=(timeout % 1000)*1000; |
2489 | + |
2490 | + /* timeout or error */ |
2491 | + if(1!=select(sd+1,&in,NULL,NULL,&tv)) |
2492 | + break; |
2493 | + |
2494 | + /* no more data (FIN or RST) */ |
2495 | + if(0>=recv(sd,buf,sizeof(buf),0)) |
2496 | + break; |
2497 | + } |
2498 | + |
2499 | +#ifdef HAVE_CLOSESOCKET |
2500 | + closesocket(sd); |
2501 | +#else |
2502 | + close(sd); |
2503 | +#endif |
2504 | + |
2505 | + return OK; |
2506 | + } |
2507 | |
2508 | === modified file 'src/nrpe.c' (properties changed: -x to +x) |
2509 | --- src/nrpe.c 2008-08-06 20:33:57 +0000 |
2510 | +++ src/nrpe.c 2013-02-02 23:23:20 +0000 |
2511 | @@ -1,1968 +1,1912 @@ |
2512 | -/******************************************************************************* |
2513 | - * |
2514 | - * NRPE.C - Nagios Remote Plugin Executor |
2515 | - * Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org) |
2516 | - * License: GPL |
2517 | - * |
2518 | - * Last Modified: 03-10-2008 |
2519 | - * |
2520 | - * Command line: nrpe -c <config_file> [--inetd | --daemon] |
2521 | - * |
2522 | - * Description: |
2523 | - * |
2524 | - * This program is designed to run as a background process and |
2525 | - * handle incoming requests (from the host running Nagios) for |
2526 | - * plugin execution. It is useful for running "local" plugins |
2527 | - * such as check_users, check_load, check_disk, etc. without |
2528 | - * having to use rsh or ssh. |
2529 | - * |
2530 | - ******************************************************************************/ |
2531 | - |
2532 | -#include "../include/common.h" |
2533 | -#include "../include/config.h" |
2534 | -#include "../include/nrpe.h" |
2535 | -#include "../include/utils.h" |
2536 | - |
2537 | -#ifdef HAVE_SSL |
2538 | -#include "../include/dh.h" |
2539 | -#endif |
2540 | - |
2541 | -#ifdef HAVE_LIBWRAP |
2542 | -int allow_severity=LOG_INFO; |
2543 | -int deny_severity=LOG_WARNING; |
2544 | -#endif |
2545 | - |
2546 | -#ifdef HAVE_SSL |
2547 | -SSL_METHOD *meth; |
2548 | -SSL_CTX *ctx; |
2549 | -int use_ssl=TRUE; |
2550 | -#else |
2551 | -int use_ssl=FALSE; |
2552 | -#endif |
2553 | - |
2554 | -#define DEFAULT_COMMAND_TIMEOUT 60 /* default timeout for execution of plugins */ |
2555 | -#define MAXFD 64 |
2556 | -#define NASTY_METACHARS "|`&><'\"\\[]{};" |
2557 | - |
2558 | -char *command_name=NULL; |
2559 | -char *macro_argv[MAX_COMMAND_ARGUMENTS]; |
2560 | - |
2561 | -char config_file[MAX_INPUT_BUFFER]="nrpe.cfg"; |
2562 | -int log_facility=LOG_DAEMON; |
2563 | -int server_port=DEFAULT_SERVER_PORT; |
2564 | -char server_address[16]="0.0.0.0"; |
2565 | -int socket_timeout=DEFAULT_SOCKET_TIMEOUT; |
2566 | -int command_timeout=DEFAULT_COMMAND_TIMEOUT; |
2567 | -int connection_timeout=DEFAULT_CONNECTION_TIMEOUT; |
2568 | -char *command_prefix=NULL; |
2569 | - |
2570 | -command *command_list=NULL; |
2571 | - |
2572 | -char *nrpe_user=NULL; |
2573 | -char *nrpe_group=NULL; |
2574 | - |
2575 | -char *allowed_hosts=NULL; |
2576 | - |
2577 | -char *pid_file=NULL; |
2578 | -int wrote_pid_file=FALSE; |
2579 | - |
2580 | -int allow_arguments=FALSE; |
2581 | - |
2582 | -int allow_weak_random_seed=FALSE; |
2583 | - |
2584 | -int sigrestart=FALSE; |
2585 | -int sigshutdown=FALSE; |
2586 | - |
2587 | -int show_help=FALSE; |
2588 | -int show_license=FALSE; |
2589 | -int show_version=FALSE; |
2590 | -int use_inetd=TRUE; |
2591 | -int debug=FALSE; |
2592 | - |
2593 | - |
2594 | - |
2595 | - |
2596 | -int main(int argc, char **argv){ |
2597 | - int result=OK; |
2598 | - int x; |
2599 | - char buffer[MAX_INPUT_BUFFER]; |
2600 | - char *env_string=NULL; |
2601 | -#ifdef HAVE_SSL |
2602 | - DH *dh; |
2603 | - char seedfile[FILENAME_MAX]; |
2604 | - int i,c; |
2605 | -#endif |
2606 | - |
2607 | - /* set some environment variables */ |
2608 | - asprintf(&env_string,"NRPE_MULTILINESUPPORT=1"); |
2609 | - putenv(env_string); |
2610 | - asprintf(&env_string,"NRPE_PROGRAMVERSION=%s",PROGRAM_VERSION); |
2611 | - putenv(env_string); |
2612 | - |
2613 | - /* process command-line args */ |
2614 | - result=process_arguments(argc,argv); |
2615 | - |
2616 | - if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){ |
2617 | - |
2618 | - printf("\n"); |
2619 | - printf("NRPE - Nagios Remote Plugin Executor\n"); |
2620 | - printf("Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)\n"); |
2621 | - printf("Version: %s\n",PROGRAM_VERSION); |
2622 | - printf("Last Modified: %s\n",MODIFICATION_DATE); |
2623 | - printf("License: GPL v2 with exemptions (-l for more info)\n"); |
2624 | -#ifdef HAVE_SSL |
2625 | - printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n"); |
2626 | -#endif |
2627 | -#ifdef HAVE_LIBWRAP |
2628 | - printf("TCP Wrappers Available\n"); |
2629 | -#endif |
2630 | - printf("\n"); |
2631 | -#ifdef ENABLE_COMMAND_ARGUMENTS |
2632 | - printf("***************************************************************\n"); |
2633 | - printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n"); |
2634 | - printf("** Read the NRPE SECURITY file for more information **\n"); |
2635 | - printf("***************************************************************\n"); |
2636 | - printf("\n"); |
2637 | -#endif |
2638 | -#ifndef HAVE_LIBWRAP |
2639 | - printf("***************************************************************\n"); |
2640 | - printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE! **\n"); |
2641 | - printf("** Read the NRPE SECURITY file for more information **\n"); |
2642 | - printf("***************************************************************\n"); |
2643 | - printf("\n"); |
2644 | -#endif |
2645 | - } |
2646 | - |
2647 | - if(show_license==TRUE) |
2648 | - display_license(); |
2649 | - |
2650 | - else if(result!=OK || show_help==TRUE){ |
2651 | - |
2652 | - printf("Usage: nrpe [-n] -c <config_file> <mode>\n"); |
2653 | - printf("\n"); |
2654 | - printf("Options:\n"); |
2655 | - printf(" -n = Do not use SSL\n"); |
2656 | - printf(" <config_file> = Name of config file to use\n"); |
2657 | - printf(" <mode> = One of the following two operating modes:\n"); |
2658 | - printf(" -i = Run as a service under inetd or xinetd\n"); |
2659 | - printf(" -d = Run as a standalone daemon\n"); |
2660 | - printf("\n"); |
2661 | - printf("Notes:\n"); |
2662 | - printf("This program is designed to process requests from the check_nrpe\n"); |
2663 | - printf("plugin on the host(s) running Nagios. It can run as a service\n"); |
2664 | - printf("under inetd or xinetd (read the docs for info on this), or as a\n"); |
2665 | - printf("standalone daemon. Once a request is received from an authorized\n"); |
2666 | - printf("host, NRPE will execute the command/plugin (as defined in the\n"); |
2667 | - printf("config file) and return the plugin output and return code to the\n"); |
2668 | - printf("check_nrpe plugin.\n"); |
2669 | - printf("\n"); |
2670 | - } |
2671 | - |
2672 | - if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE) |
2673 | - exit(STATE_UNKNOWN); |
2674 | - |
2675 | - |
2676 | - /* open a connection to the syslog facility */ |
2677 | - /* facility name may be overridden later */ |
2678 | - get_log_facility(NRPE_LOG_FACILITY); |
2679 | - openlog("nrpe",LOG_PID,log_facility); |
2680 | - |
2681 | - /* make sure the config file uses an absolute path */ |
2682 | - if(config_file[0]!='/'){ |
2683 | - |
2684 | - /* save the name of the config file */ |
2685 | - strncpy(buffer,config_file,sizeof(buffer)); |
2686 | - buffer[sizeof(buffer)-1]='\x0'; |
2687 | - |
2688 | - /* get absolute path of current working directory */ |
2689 | - strcpy(config_file,""); |
2690 | - getcwd(config_file,sizeof(config_file)); |
2691 | - |
2692 | - /* append a forward slash */ |
2693 | - strncat(config_file,"/",sizeof(config_file)-2); |
2694 | - config_file[sizeof(config_file)-1]='\x0'; |
2695 | - |
2696 | - /* append the config file to the path */ |
2697 | - strncat(config_file,buffer,sizeof(config_file)-strlen(config_file)-1); |
2698 | - config_file[sizeof(config_file)-1]='\x0'; |
2699 | - } |
2700 | - |
2701 | - /* read the config file */ |
2702 | - result=read_config_file(config_file); |
2703 | - |
2704 | - /* exit if there are errors... */ |
2705 | - if(result==ERROR){ |
2706 | - syslog(LOG_ERR,"Config file '%s' contained errors, aborting...",config_file); |
2707 | - return STATE_CRITICAL; |
2708 | - } |
2709 | - |
2710 | - /* generate the CRC 32 table */ |
2711 | - generate_crc32_table(); |
2712 | - |
2713 | - /* initialize macros */ |
2714 | - for(x=0;x<MAX_COMMAND_ARGUMENTS;x++) |
2715 | - macro_argv[x]=NULL; |
2716 | - |
2717 | -#ifdef HAVE_SSL |
2718 | - /* initialize SSL */ |
2719 | - if(use_ssl==TRUE){ |
2720 | - SSL_library_init(); |
2721 | - SSLeay_add_ssl_algorithms(); |
2722 | - meth=SSLv23_server_method(); |
2723 | - SSL_load_error_strings(); |
2724 | - |
2725 | - /* use week random seed if necessary */ |
2726 | - if(allow_weak_random_seed && (RAND_status()==0)){ |
2727 | - |
2728 | - if(RAND_file_name(seedfile,sizeof(seedfile)-1)) |
2729 | - if(RAND_load_file(seedfile,-1)) |
2730 | - RAND_write_file(seedfile); |
2731 | - |
2732 | - if(RAND_status()==0){ |
2733 | - syslog(LOG_ERR,"Warning: SSL/TLS uses a weak random seed which is highly discouraged"); |
2734 | - srand(time(NULL)); |
2735 | - for(i=0;i<500 && RAND_status()==0;i++){ |
2736 | - for(c=0;c<sizeof(seedfile);c+=sizeof(int)){ |
2737 | - *((int *)(seedfile+c))=rand(); |
2738 | - } |
2739 | - RAND_seed(seedfile,sizeof(seedfile)); |
2740 | - } |
2741 | - } |
2742 | - } |
2743 | - |
2744 | - if((ctx=SSL_CTX_new(meth))==NULL){ |
2745 | - syslog(LOG_ERR,"Error: could not create SSL context.\n"); |
2746 | - exit(STATE_CRITICAL); |
2747 | - } |
2748 | - |
2749 | - /* ADDED 01/19/2004 */ |
2750 | - /* use only TLSv1 protocol */ |
2751 | - SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); |
2752 | - |
2753 | - /* use anonymous DH ciphers */ |
2754 | - SSL_CTX_set_cipher_list(ctx,"ADH"); |
2755 | - dh=get_dh512(); |
2756 | - SSL_CTX_set_tmp_dh(ctx,dh); |
2757 | - DH_free(dh); |
2758 | - if(debug==TRUE) |
2759 | - syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted."); |
2760 | - } |
2761 | - else{ |
2762 | - if(debug==TRUE) |
2763 | - syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED."); |
2764 | - } |
2765 | -#endif |
2766 | - |
2767 | - /* if we're running under inetd... */ |
2768 | - if(use_inetd==TRUE){ |
2769 | - |
2770 | - /* make sure we're not root */ |
2771 | - check_privileges(); |
2772 | - |
2773 | - /* redirect STDERR to /dev/null */ |
2774 | - close(2); |
2775 | - open("/dev/null",O_WRONLY); |
2776 | - |
2777 | - /* handle the connection */ |
2778 | - handle_connection(0); |
2779 | - } |
2780 | - |
2781 | - /* else daemonize and start listening for requests... */ |
2782 | - else if(fork()==0){ |
2783 | - |
2784 | - /* we're a daemon - set up a new process group */ |
2785 | - setsid(); |
2786 | - |
2787 | - /* close standard file descriptors */ |
2788 | - close(0); |
2789 | - close(1); |
2790 | - close(2); |
2791 | - |
2792 | - /* redirect standard descriptors to /dev/null */ |
2793 | - open("/dev/null",O_RDONLY); |
2794 | - open("/dev/null",O_WRONLY); |
2795 | - open("/dev/null",O_WRONLY); |
2796 | - |
2797 | - chdir("/"); |
2798 | - /*umask(0);*/ |
2799 | - |
2800 | - /* handle signals */ |
2801 | - signal(SIGQUIT,sighandler); |
2802 | - signal(SIGTERM,sighandler); |
2803 | - signal(SIGHUP,sighandler); |
2804 | - |
2805 | - /* log info to syslog facility */ |
2806 | - syslog(LOG_NOTICE,"Starting up daemon"); |
2807 | - |
2808 | - /* write pid file */ |
2809 | - if(write_pid_file()==ERROR) |
2810 | - return STATE_CRITICAL; |
2811 | - |
2812 | - /* drop privileges */ |
2813 | - drop_privileges(nrpe_user,nrpe_group); |
2814 | - |
2815 | - /* make sure we're not root */ |
2816 | - check_privileges(); |
2817 | - |
2818 | - do{ |
2819 | - |
2820 | - /* reset flags */ |
2821 | - sigrestart=FALSE; |
2822 | - sigshutdown=FALSE; |
2823 | - |
2824 | - /* wait for connections */ |
2825 | - wait_for_connections(); |
2826 | - |
2827 | - /* free all memory we allocated */ |
2828 | - free_memory(); |
2829 | - |
2830 | - if(sigrestart==TRUE){ |
2831 | - |
2832 | - /* read the config file */ |
2833 | - result=read_config_file(config_file); |
2834 | - |
2835 | - /* exit if there are errors... */ |
2836 | - if(result==ERROR){ |
2837 | - syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file); |
2838 | - return STATE_CRITICAL; |
2839 | - } |
2840 | - } |
2841 | - |
2842 | - }while(sigrestart==TRUE && sigshutdown==FALSE); |
2843 | - |
2844 | - /* remove pid file */ |
2845 | - remove_pid_file(); |
2846 | - |
2847 | - syslog(LOG_NOTICE,"Daemon shutdown\n"); |
2848 | - } |
2849 | - |
2850 | -#ifdef HAVE_SSL |
2851 | - if(use_ssl==TRUE) |
2852 | - SSL_CTX_free(ctx); |
2853 | -#endif |
2854 | - |
2855 | - /* We are now running in daemon mode, or the connection handed over by inetd has |
2856 | - been completed, so the parent process exits */ |
2857 | - return STATE_OK; |
2858 | - } |
2859 | - |
2860 | - |
2861 | - |
2862 | - |
2863 | -/* read in the configuration file */ |
2864 | -int read_config_file(char *filename){ |
2865 | - FILE *fp; |
2866 | - char config_file[MAX_FILENAME_LENGTH]; |
2867 | - char input_buffer[MAX_INPUT_BUFFER]; |
2868 | - char *input_line; |
2869 | - char *temp_buffer; |
2870 | - char *varname; |
2871 | - char *varvalue; |
2872 | - int line=0; |
2873 | - int len=0; |
2874 | - int x=0; |
2875 | - |
2876 | - |
2877 | - /* open the config file for reading */ |
2878 | - fp=fopen(filename,"r"); |
2879 | - |
2880 | - /* exit if we couldn't open the config file */ |
2881 | - if(fp==NULL){ |
2882 | - syslog(LOG_ERR,"Unable to open config file '%s' for reading\n",filename); |
2883 | - return ERROR; |
2884 | - } |
2885 | - |
2886 | - while(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){ |
2887 | - |
2888 | - line++; |
2889 | - input_line=input_buffer; |
2890 | - |
2891 | - /* skip leading whitespace */ |
2892 | - while(isspace(*input_line)) |
2893 | - ++input_line; |
2894 | - |
2895 | - /* trim trailing whitespace */ |
2896 | - len=strlen(input_line); |
2897 | - for(x=len-1;x>=0;x--){ |
2898 | - if(isspace(input_line[x])) |
2899 | - input_line[x]='\x0'; |
2900 | - else |
2901 | - break; |
2902 | - } |
2903 | - |
2904 | - /* skip comments and blank lines */ |
2905 | - if(input_line[0]=='#') |
2906 | - continue; |
2907 | - if(input_line[0]=='\x0') |
2908 | - continue; |
2909 | - if(input_line[0]=='\n') |
2910 | - continue; |
2911 | - |
2912 | - /* get the variable name */ |
2913 | - varname=strtok(input_line,"="); |
2914 | - if(varname==NULL){ |
2915 | - syslog(LOG_ERR,"No variable name specified in config file '%s' - Line %d\n",filename,line); |
2916 | - return ERROR; |
2917 | - } |
2918 | - |
2919 | - /* get the variable value */ |
2920 | - varvalue=strtok(NULL,"\n"); |
2921 | - if(varvalue==NULL){ |
2922 | - syslog(LOG_ERR,"No variable value specified in config file '%s' - Line %d\n",filename,line); |
2923 | - return ERROR; |
2924 | - } |
2925 | - |
2926 | - /* allow users to specify directories to recurse into for config files */ |
2927 | - else if(!strcmp(varname,"include_dir")){ |
2928 | - |
2929 | - strncpy(config_file,varvalue,sizeof(config_file)-1); |
2930 | - config_file[sizeof(config_file)-1]='\x0'; |
2931 | - |
2932 | - /* strip trailing / if necessary */ |
2933 | - if(config_file[strlen(config_file)-1]=='/') |
2934 | - config_file[strlen(config_file)-1]='\x0'; |
2935 | - |
2936 | - /* process the config directory... */ |
2937 | - if(read_config_dir(config_file)==ERROR) |
2938 | - syslog(LOG_ERR,"Continuing with errors..."); |
2939 | - } |
2940 | - |
2941 | - /* allow users to specify individual config files to include */ |
2942 | - else if(!strcmp(varname,"include") || !strcmp(varname,"include_file")){ |
2943 | - |
2944 | - /* process the config file... */ |
2945 | - if(read_config_file(varvalue)==ERROR) |
2946 | - syslog(LOG_ERR,"Continuing with errors..."); |
2947 | - } |
2948 | - |
2949 | - else if(!strcmp(varname,"server_port")){ |
2950 | - server_port=atoi(varvalue); |
2951 | - if(server_port<1024){ |
2952 | - syslog(LOG_ERR,"Invalid port number specified in config file '%s' - Line %d\n",filename,line); |
2953 | - return ERROR; |
2954 | - } |
2955 | - } |
2956 | - else if(!strcmp(varname,"command_prefix")) |
2957 | - command_prefix=strdup(varvalue); |
2958 | - |
2959 | - else if(!strcmp(varname,"server_address")){ |
2960 | - strncpy(server_address,varvalue,sizeof(server_address) - 1); |
2961 | - server_address[sizeof(server_address)-1]='\0'; |
2962 | - } |
2963 | - |
2964 | - else if(!strcmp(varname,"allowed_hosts")) |
2965 | - allowed_hosts=strdup(varvalue); |
2966 | - |
2967 | - else if(strstr(input_line,"command[")){ |
2968 | - temp_buffer=strtok(varname,"["); |
2969 | - temp_buffer=strtok(NULL,"]"); |
2970 | - if(temp_buffer==NULL){ |
2971 | - syslog(LOG_ERR,"Invalid command specified in config file '%s' - Line %d\n",filename,line); |
2972 | - return ERROR; |
2973 | - } |
2974 | - add_command(temp_buffer,varvalue); |
2975 | - } |
2976 | - |
2977 | - else if(strstr(input_buffer,"debug")){ |
2978 | - debug=atoi(varvalue); |
2979 | - if(debug>0) |
2980 | - debug=TRUE; |
2981 | - else |
2982 | - debug=FALSE; |
2983 | - } |
2984 | - |
2985 | - else if(!strcmp(varname,"nrpe_user")) |
2986 | - nrpe_user=strdup(varvalue); |
2987 | - |
2988 | - else if(!strcmp(varname,"nrpe_group")) |
2989 | - nrpe_group=strdup(varvalue); |
2990 | - |
2991 | - else if(!strcmp(varname,"dont_blame_nrpe")) |
2992 | - allow_arguments=(atoi(varvalue)==1)?TRUE:FALSE; |
2993 | - |
2994 | - else if(!strcmp(varname,"command_timeout")){ |
2995 | - command_timeout=atoi(varvalue); |
2996 | - if(command_timeout<1){ |
2997 | - syslog(LOG_ERR,"Invalid command_timeout specified in config file '%s' - Line %d\n",filename,line); |
2998 | - return ERROR; |
2999 | - } |
3000 | - } |
3001 | - |
3002 | - else if(!strcmp(varname,"connection_timeout")){ |
3003 | - connection_timeout=atoi(varvalue); |
3004 | - if(connection_timeout<1){ |
3005 | - syslog(LOG_ERR,"Invalid connection_timeout specified in config file '%s' - Line %d\n",filename,line); |
3006 | - return ERROR; |
3007 | - } |
3008 | - } |
3009 | - |
3010 | - else if(!strcmp(varname,"allow_weak_random_seed")) |
3011 | - allow_weak_random_seed=(atoi(varvalue)==1)?TRUE:FALSE; |
3012 | - |
3013 | - else if(!strcmp(varname,"pid_file")) |
3014 | - pid_file=strdup(varvalue); |
3015 | - |
3016 | - else if(!strcmp(varname,"log_facility")){ |
3017 | - if((get_log_facility(varvalue))==OK){ |
3018 | - /* re-open log using new facility */ |
3019 | - closelog(); |
3020 | - openlog("nrpe",LOG_PID,log_facility); |
3021 | - } |
3022 | - else |
3023 | - syslog(LOG_WARNING,"Invalid log_facility specified in config file '%s' - Line %d\n",filename,line); |
3024 | - } |
3025 | - |
3026 | - else{ |
3027 | - syslog(LOG_WARNING,"Unknown option specified in config file '%s' - Line %d\n",filename,line); |
3028 | - continue; |
3029 | - } |
3030 | - |
3031 | - } |
3032 | - |
3033 | - |
3034 | - /* close the config file */ |
3035 | - fclose(fp); |
3036 | - |
3037 | - return OK; |
3038 | - } |
3039 | - |
3040 | - |
3041 | -/* process all config files in a specific config directory (with directory recursion) */ |
3042 | -int read_config_dir(char *dirname){ |
3043 | - char config_file[MAX_FILENAME_LENGTH]; |
3044 | - DIR *dirp; |
3045 | - struct dirent *dirfile; |
3046 | - struct stat buf; |
3047 | - int result=OK; |
3048 | - int x; |
3049 | - |
3050 | - /* open the directory for reading */ |
3051 | - dirp=opendir(dirname); |
3052 | - if(dirp==NULL){ |
3053 | - syslog(LOG_ERR,"Could not open config directory '%s' for reading.\n",dirname); |
3054 | - return ERROR; |
3055 | - } |
3056 | - |
3057 | - /* process all files in the directory... */ |
3058 | - while((dirfile=readdir(dirp))!=NULL){ |
3059 | - |
3060 | - /* create the full path to the config file or subdirectory */ |
3061 | - snprintf(config_file,sizeof(config_file)-1,"%s/%s",dirname,dirfile->d_name); |
3062 | - config_file[sizeof(config_file)-1]='\x0'; |
3063 | - stat(config_file, &buf); |
3064 | - |
3065 | - /* process this if it's a config file... */ |
3066 | - x=strlen(dirfile->d_name); |
3067 | - if(x>4 && !strcmp(dirfile->d_name+(x-4),".cfg")){ |
3068 | - |
3069 | - /* only process normal files */ |
3070 | - if(!S_ISREG(buf.st_mode)) |
3071 | - continue; |
3072 | - |
3073 | - /* process the config file */ |
3074 | - result=read_config_file(config_file); |
3075 | - |
3076 | - /* break out if we encountered an error */ |
3077 | - if(result==ERROR) |
3078 | - break; |
3079 | - } |
3080 | - |
3081 | - /* recurse into subdirectories... */ |
3082 | - if(S_ISDIR(buf.st_mode)){ |
3083 | - |
3084 | - /* ignore current, parent and hidden directory entries */ |
3085 | - if(dirfile->d_name[0]=='.') |
3086 | - continue; |
3087 | - |
3088 | - /* process the config directory */ |
3089 | - result=read_config_dir(config_file); |
3090 | - |
3091 | - /* break out if we encountered an error */ |
3092 | - if(result==ERROR) |
3093 | - break; |
3094 | - } |
3095 | - } |
3096 | - |
3097 | - closedir(dirp); |
3098 | - |
3099 | - return result; |
3100 | - } |
3101 | - |
3102 | - |
3103 | - |
3104 | -/* determines facility to use with syslog */ |
3105 | -int get_log_facility(char *varvalue){ |
3106 | - |
3107 | - if(!strcmp(varvalue,"kern")) |
3108 | - log_facility=LOG_KERN; |
3109 | - else if(!strcmp(varvalue,"user")) |
3110 | - log_facility=LOG_USER; |
3111 | - else if(!strcmp(varvalue,"mail")) |
3112 | - log_facility=LOG_MAIL; |
3113 | - else if(!strcmp(varvalue,"daemon")) |
3114 | - log_facility=LOG_DAEMON; |
3115 | - else if(!strcmp(varvalue,"auth")) |
3116 | - log_facility=LOG_AUTH; |
3117 | - else if(!strcmp(varvalue,"syslog")) |
3118 | - log_facility=LOG_SYSLOG; |
3119 | - else if(!strcmp(varvalue,"lrp")) |
3120 | - log_facility=LOG_LPR; |
3121 | - else if(!strcmp(varvalue,"news")) |
3122 | - log_facility=LOG_NEWS; |
3123 | - else if(!strcmp(varvalue,"uucp")) |
3124 | - log_facility=LOG_UUCP; |
3125 | - else if(!strcmp(varvalue,"cron")) |
3126 | - log_facility=LOG_CRON; |
3127 | - else if(!strcmp(varvalue,"authpriv")) |
3128 | - log_facility=LOG_AUTHPRIV; |
3129 | - else if(!strcmp(varvalue,"ftp")) |
3130 | - log_facility=LOG_FTP; |
3131 | - else if(!strcmp(varvalue,"local0")) |
3132 | - log_facility=LOG_LOCAL0; |
3133 | - else if(!strcmp(varvalue,"local1")) |
3134 | - log_facility=LOG_LOCAL1; |
3135 | - else if(!strcmp(varvalue,"local2")) |
3136 | - log_facility=LOG_LOCAL2; |
3137 | - else if(!strcmp(varvalue,"local3")) |
3138 | - log_facility=LOG_LOCAL3; |
3139 | - else if(!strcmp(varvalue,"local4")) |
3140 | - log_facility=LOG_LOCAL4; |
3141 | - else if(!strcmp(varvalue,"local5")) |
3142 | - log_facility=LOG_LOCAL5; |
3143 | - else if(!strcmp(varvalue,"local6")) |
3144 | - log_facility=LOG_LOCAL6; |
3145 | - else if(!strcmp(varvalue,"local7")) |
3146 | - log_facility=LOG_LOCAL7; |
3147 | - else{ |
3148 | - log_facility=LOG_DAEMON; |
3149 | - return ERROR; |
3150 | - } |
3151 | - |
3152 | - return OK; |
3153 | - } |
3154 | - |
3155 | - |
3156 | - |
3157 | -/* adds a new command definition from the config file to the list in memory */ |
3158 | -int add_command(char *command_name, char *command_line){ |
3159 | - command *new_command; |
3160 | - |
3161 | - if(command_name==NULL || command_line==NULL) |
3162 | - return ERROR; |
3163 | - |
3164 | - /* allocate memory for the new command */ |
3165 | - new_command=(command *)malloc(sizeof(command)); |
3166 | - if(new_command==NULL) |
3167 | - return ERROR; |
3168 | - |
3169 | - new_command->command_name=strdup(command_name); |
3170 | - if(new_command->command_name==NULL){ |
3171 | - free(new_command); |
3172 | - return ERROR; |
3173 | - } |
3174 | - new_command->command_line=strdup(command_line); |
3175 | - if(new_command->command_line==NULL){ |
3176 | - free(new_command->command_name); |
3177 | - free(new_command); |
3178 | - return ERROR; |
3179 | - } |
3180 | - |
3181 | - /* add new command to head of list in memory */ |
3182 | - new_command->next=command_list; |
3183 | - command_list=new_command; |
3184 | - |
3185 | - if(debug==TRUE) |
3186 | - syslog(LOG_DEBUG,"Added command[%s]=%s\n",command_name,command_line); |
3187 | - |
3188 | - return OK; |
3189 | - } |
3190 | - |
3191 | - |
3192 | - |
3193 | -/* given a command name, find the structure in memory */ |
3194 | -command *find_command(char *command_name){ |
3195 | - command *temp_command; |
3196 | - |
3197 | - for(temp_command=command_list;temp_command!=NULL;temp_command=temp_command->next) |
3198 | - if(!strcmp(command_name,temp_command->command_name)) |
3199 | - return temp_command; |
3200 | - |
3201 | - return NULL; |
3202 | - } |
3203 | - |
3204 | - |
3205 | - |
3206 | -/* wait for incoming connection requests */ |
3207 | -void wait_for_connections(void){ |
3208 | - struct sockaddr_in myname; |
3209 | - struct sockaddr_in *nptr; |
3210 | - struct sockaddr addr; |
3211 | - int rc; |
3212 | - int sock, new_sd; |
3213 | - socklen_t addrlen; |
3214 | - pid_t pid; |
3215 | - int flag=1; |
3216 | - fd_set fdread; |
3217 | - struct timeval timeout; |
3218 | - int retval; |
3219 | -#ifdef HAVE_LIBWRAP |
3220 | - struct request_info req; |
3221 | -#endif |
3222 | - |
3223 | - /* create a socket for listening */ |
3224 | - sock=socket(AF_INET,SOCK_STREAM,0); |
3225 | - |
3226 | - /* exit if we couldn't create the socket */ |
3227 | - if(sock<0){ |
3228 | - syslog(LOG_ERR,"Network server socket failure (%d: %s)",errno,strerror(errno)); |
3229 | - exit(STATE_CRITICAL); |
3230 | - } |
3231 | - |
3232 | - /* socket should be non-blocking */ |
3233 | - fcntl(sock,F_SETFL,O_NONBLOCK); |
3234 | - |
3235 | - /* set the reuse address flag so we don't get errors when restarting */ |
3236 | - flag=1; |
3237 | - if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){ |
3238 | - syslog(LOG_ERR,"Could not set reuse address option on socket!\n"); |
3239 | - exit(STATE_UNKNOWN); |
3240 | - } |
3241 | - |
3242 | - myname.sin_family=AF_INET; |
3243 | - myname.sin_port=htons(server_port); |
3244 | - bzero(&myname.sin_zero,8); |
3245 | - |
3246 | - /* what address should we bind to? */ |
3247 | - if(!strlen(server_address)) |
3248 | - myname.sin_addr.s_addr=INADDR_ANY; |
3249 | - |
3250 | - else if(!my_inet_aton(server_address,&myname.sin_addr)){ |
3251 | - syslog(LOG_ERR,"Server address is not a valid IP address\n"); |
3252 | - exit(STATE_CRITICAL); |
3253 | - } |
3254 | - |
3255 | - /* bind the address to the Internet socket */ |
3256 | - if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){ |
3257 | - syslog(LOG_ERR,"Network server bind failure (%d: %s)\n",errno,strerror(errno)); |
3258 | - exit(STATE_CRITICAL); |
3259 | - } |
3260 | - |
3261 | - /* open the socket for listening */ |
3262 | - if(listen(sock,5)<0){ |
3263 | - syslog(LOG_ERR,"Network server listen failure (%d: %s)\n",errno,strerror(errno)); |
3264 | - exit(STATE_CRITICAL); |
3265 | - } |
3266 | - |
3267 | - /* log warning about command arguments */ |
3268 | -#ifdef ENABLE_COMMAND_ARGUMENTS |
3269 | - if(allow_arguments==TRUE) |
3270 | - syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments from clients!"); |
3271 | -#endif |
3272 | - |
3273 | - syslog(LOG_INFO,"Listening for connections on port %d\n",htons(myname.sin_port)); |
3274 | - |
3275 | - if(allowed_hosts) |
3276 | - syslog(LOG_INFO,"Allowing connections from: %s\n",allowed_hosts); |
3277 | - |
3278 | - /* listen for connection requests - fork() if we get one */ |
3279 | - while(1){ |
3280 | - |
3281 | - /* wait for a connection request */ |
3282 | - while(1){ |
3283 | - |
3284 | - /* wait until there's something to do */ |
3285 | - FD_ZERO(&fdread); |
3286 | - FD_SET(sock,&fdread); |
3287 | - timeout.tv_sec=0; |
3288 | - timeout.tv_usec=500000; |
3289 | - retval=select(sock+1,&fdread,NULL,&fdread,&timeout); |
3290 | - |
3291 | - /* bail out if necessary */ |
3292 | - if(sigrestart==TRUE || sigshutdown==TRUE) |
3293 | - break; |
3294 | - |
3295 | - /* error */ |
3296 | - if(retval<0) |
3297 | - continue; |
3298 | - |
3299 | - /* accept a new connection request */ |
3300 | - new_sd=accept(sock,0,0); |
3301 | - |
3302 | - /* some kind of error occurred... */ |
3303 | - if(new_sd<0){ |
3304 | - |
3305 | - /* bail out if necessary */ |
3306 | - if(sigrestart==TRUE || sigshutdown==TRUE) |
3307 | - break; |
3308 | - |
3309 | - /* retry */ |
3310 | - if(errno==EWOULDBLOCK || errno==EINTR) |
3311 | - continue; |
3312 | - |
3313 | - /* socket is nonblocking and we don't have a connection yet */ |
3314 | - if(errno==EAGAIN) |
3315 | - continue; |
3316 | - |
3317 | - /* fix for HP-UX 11.0 - just retry */ |
3318 | - if(errno==ENOBUFS) |
3319 | - continue; |
3320 | - |
3321 | - /* else handle the error later */ |
3322 | - break; |
3323 | - } |
3324 | - |
3325 | - /* connection was good */ |
3326 | - break; |
3327 | - } |
3328 | - |
3329 | - /* bail out if necessary */ |
3330 | - if(sigrestart==TRUE || sigshutdown==TRUE) |
3331 | - break; |
3332 | - |
3333 | - /* child process should handle the connection */ |
3334 | - pid=fork(); |
3335 | - if(pid==0){ |
3336 | - |
3337 | - /* fork again so we don't create zombies */ |
3338 | - pid=fork(); |
3339 | - if(pid==0){ |
3340 | - |
3341 | - /* hey, there was an error... */ |
3342 | - if(new_sd<0){ |
3343 | - |
3344 | - /* log error to syslog facility */ |
3345 | - syslog(LOG_ERR,"Network server accept failure (%d: %s)",errno,strerror(errno)); |
3346 | - |
3347 | - /* close socket prioer to exiting */ |
3348 | - close(sock); |
3349 | - |
3350 | - return; |
3351 | - } |
3352 | - |
3353 | - /* handle signals */ |
3354 | - signal(SIGQUIT,child_sighandler); |
3355 | - signal(SIGTERM,child_sighandler); |
3356 | - signal(SIGHUP,child_sighandler); |
3357 | - |
3358 | - /* grandchild does not need to listen for connections, so close the socket */ |
3359 | - close(sock); |
3360 | - |
3361 | - /* find out who just connected... */ |
3362 | - addrlen=sizeof(addr); |
3363 | - rc=getpeername(new_sd,&addr,&addrlen); |
3364 | - |
3365 | - if(rc<0){ |
3366 | - |
3367 | - /* log error to syslog facility */ |
3368 | - syslog(LOG_ERR,"Error: Network server getpeername() failure (%d: %s)",errno,strerror(errno)); |
3369 | - |
3370 | - /* close socket prior to exiting */ |
3371 | - close(new_sd); |
3372 | - |
3373 | - return; |
3374 | - } |
3375 | - |
3376 | - nptr=(struct sockaddr_in *)&addr; |
3377 | - |
3378 | - /* log info to syslog facility */ |
3379 | - if(debug==TRUE) |
3380 | - syslog(LOG_DEBUG,"Connection from %s port %d",inet_ntoa(nptr->sin_addr),nptr->sin_port); |
3381 | - |
3382 | - /* is this is a blessed machine? */ |
3383 | - if(allowed_hosts){ |
3384 | - |
3385 | - if(!is_an_allowed_host(inet_ntoa(nptr->sin_addr))){ |
3386 | - |
3387 | - /* log error to syslog facility */ |
3388 | - syslog(LOG_ERR,"Host %s is not allowed to talk to us!",inet_ntoa(nptr->sin_addr)); |
3389 | - |
3390 | - /* log info to syslog facility */ |
3391 | - if(debug==TRUE) |
3392 | - syslog(LOG_DEBUG,"Connection from %s closed.",inet_ntoa(nptr->sin_addr)); |
3393 | - |
3394 | - /* close socket prior to exiting */ |
3395 | - close(new_sd); |
3396 | - |
3397 | - exit(STATE_OK); |
3398 | - } |
3399 | - else{ |
3400 | - |
3401 | - /* log info to syslog facility */ |
3402 | - if(debug==TRUE) |
3403 | - syslog(LOG_DEBUG,"Host address is in allowed_hosts"); |
3404 | - } |
3405 | - } |
3406 | - |
3407 | -#ifdef HAVE_LIBWRAP |
3408 | - |
3409 | - /* Check whether or not connections are allowed from this host */ |
3410 | - request_init(&req,RQ_DAEMON,"nrpe",RQ_FILE,new_sd,0); |
3411 | - fromhost(&req); |
3412 | - |
3413 | - if(!hosts_access(&req)){ |
3414 | - |
3415 | - syslog(LOG_DEBUG,"Connection refused by TCP wrapper"); |
3416 | - |
3417 | - /* refuse the connection */ |
3418 | - refuse(&req); |
3419 | - close(new_sd); |
3420 | - |
3421 | - /* should not be reached */ |
3422 | - syslog(LOG_ERR,"libwrap refuse() returns!"); |
3423 | - exit(STATE_CRITICAL); |
3424 | - } |
3425 | -#endif |
3426 | - |
3427 | - /* handle the client connection */ |
3428 | - handle_connection(new_sd); |
3429 | - |
3430 | - /* log info to syslog facility */ |
3431 | - if(debug==TRUE) |
3432 | - syslog(LOG_DEBUG,"Connection from %s closed.",inet_ntoa(nptr->sin_addr)); |
3433 | - |
3434 | - /* close socket prior to exiting */ |
3435 | - close(new_sd); |
3436 | - |
3437 | - exit(STATE_OK); |
3438 | - } |
3439 | - |
3440 | - /* first child returns immediately, grandchild is inherited by INIT process -> no zombies... */ |
3441 | - else |
3442 | - exit(STATE_OK); |
3443 | - } |
3444 | - |
3445 | - /* parent ... */ |
3446 | - else{ |
3447 | - /* parent doesn't need the new connection */ |
3448 | - close(new_sd); |
3449 | - |
3450 | - /* parent waits for first child to exit */ |
3451 | - waitpid(pid,NULL,0); |
3452 | - } |
3453 | - } |
3454 | - |
3455 | - /* close the socket we're listening on */ |
3456 | - close(sock); |
3457 | - |
3458 | - return; |
3459 | - } |
3460 | - |
3461 | - |
3462 | - |
3463 | -/* checks to see if a given host is allowed to talk to us */ |
3464 | -int is_an_allowed_host(char *connecting_host){ |
3465 | - char *temp_buffer=NULL; |
3466 | - char *temp_ptr=NULL; |
3467 | - int result=0; |
3468 | - struct hostent *myhost; |
3469 | - char **pptr=NULL; |
3470 | - char *save_connecting_host=NULL; |
3471 | - struct in_addr addr; |
3472 | - |
3473 | - /* make sure we have something */ |
3474 | - if(connecting_host==NULL) |
3475 | - return 0; |
3476 | - if(allowed_hosts==NULL) |
3477 | - return 1; |
3478 | - |
3479 | - if((temp_buffer=strdup(allowed_hosts))==NULL) |
3480 | - return 0; |
3481 | - |
3482 | - /* try and match IP addresses first */ |
3483 | - for(temp_ptr=strtok(temp_buffer,",");temp_ptr!=NULL;temp_ptr=strtok(NULL,",")){ |
3484 | - |
3485 | - if(!strcmp(connecting_host,temp_ptr)){ |
3486 | - result=1; |
3487 | - break; |
3488 | - } |
3489 | - } |
3490 | - |
3491 | - /* try DNS lookups if needed */ |
3492 | - if(result==0){ |
3493 | - |
3494 | - free(temp_buffer); |
3495 | - if((temp_buffer=strdup(allowed_hosts))==NULL) |
3496 | - return 0; |
3497 | - |
3498 | - save_connecting_host=strdup(connecting_host); |
3499 | - for(temp_ptr=strtok(temp_buffer,",");temp_ptr!=NULL;temp_ptr=strtok(NULL,",")){ |
3500 | - |
3501 | - myhost=gethostbyname(temp_ptr); |
3502 | - if(myhost!=NULL){ |
3503 | - |
3504 | - /* check all addresses for the host... */ |
3505 | - for(pptr=myhost->h_addr_list;*pptr!=NULL;pptr++){ |
3506 | - memcpy(&addr, *pptr, sizeof(addr)); |
3507 | - if(!strcmp(save_connecting_host, inet_ntoa(addr))){ |
3508 | - result=1; |
3509 | - break; |
3510 | - } |
3511 | - } |
3512 | - } |
3513 | - |
3514 | - if(result==1) |
3515 | - break; |
3516 | - } |
3517 | - |
3518 | - strcpy(connecting_host, save_connecting_host); |
3519 | - free(save_connecting_host); |
3520 | - } |
3521 | - |
3522 | - free(temp_buffer); |
3523 | - |
3524 | - return result; |
3525 | - } |
3526 | - |
3527 | - |
3528 | - |
3529 | -/* handles a client connection */ |
3530 | -void handle_connection(int sock){ |
3531 | - u_int32_t calculated_crc32; |
3532 | - command *temp_command; |
3533 | - packet receive_packet; |
3534 | - packet send_packet; |
3535 | - int bytes_to_send; |
3536 | - int bytes_to_recv; |
3537 | - char buffer[MAX_INPUT_BUFFER]; |
3538 | - char raw_command[MAX_INPUT_BUFFER]; |
3539 | - char processed_command[MAX_INPUT_BUFFER]; |
3540 | - int result=STATE_OK; |
3541 | - int early_timeout=FALSE; |
3542 | - int rc; |
3543 | - int x; |
3544 | -#ifdef DEBUG |
3545 | - FILE *errfp; |
3546 | -#endif |
3547 | -#ifdef HAVE_SSL |
3548 | - SSL *ssl=NULL; |
3549 | -#endif |
3550 | - |
3551 | - |
3552 | - /* log info to syslog facility */ |
3553 | - if(debug==TRUE) |
3554 | - syslog(LOG_DEBUG,"Handling the connection..."); |
3555 | - |
3556 | -#ifdef OLDSTUFF |
3557 | - /* socket should be non-blocking */ |
3558 | - fcntl(sock,F_SETFL,O_NONBLOCK); |
3559 | -#endif |
3560 | - |
3561 | - /* set connection handler */ |
3562 | - signal(SIGALRM,my_connection_sighandler); |
3563 | - alarm(connection_timeout); |
3564 | - |
3565 | -#ifdef HAVE_SSL |
3566 | - /* do SSL handshake */ |
3567 | - if(result==STATE_OK && use_ssl==TRUE){ |
3568 | - if((ssl=SSL_new(ctx))!=NULL){ |
3569 | - SSL_set_fd(ssl,sock); |
3570 | - |
3571 | - /* keep attempting the request if needed */ |
3572 | - while(((rc=SSL_accept(ssl))!=1) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ)); |
3573 | - |
3574 | - if(rc!=1){ |
3575 | - syslog(LOG_ERR,"Error: Could not complete SSL handshake. %d\n",SSL_get_error(ssl,rc)); |
3576 | -#ifdef DEBUG |
3577 | - errfp=fopen("/tmp/err.log","w"); |
3578 | - ERR_print_errors_fp(errfp); |
3579 | - fclose(errfp); |
3580 | -#endif |
3581 | - return; |
3582 | - } |
3583 | - } |
3584 | - else{ |
3585 | - syslog(LOG_ERR,"Error: Could not create SSL connection structure.\n"); |
3586 | -#ifdef DEBUG |
3587 | - errfp=fopen("/tmp/err.log","w"); |
3588 | - ERR_print_errors_fp(errfp); |
3589 | - fclose(errfp); |
3590 | -#endif |
3591 | - return; |
3592 | - } |
3593 | - } |
3594 | -#endif |
3595 | - |
3596 | - bytes_to_recv=sizeof(receive_packet); |
3597 | - if(use_ssl==FALSE) |
3598 | - rc=recvall(sock,(char *)&receive_packet,&bytes_to_recv,socket_timeout); |
3599 | -#ifdef HAVE_SSL |
3600 | - else{ |
3601 | - while(((rc=SSL_read(ssl,&receive_packet,bytes_to_recv))<=0) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ)); |
3602 | - } |
3603 | -#endif |
3604 | - |
3605 | - /* recv() error or client disconnect */ |
3606 | - if(rc<=0){ |
3607 | - |
3608 | - /* log error to syslog facility */ |
3609 | - syslog(LOG_ERR,"Could not read request from client, bailing out..."); |
3610 | - |
3611 | -#ifdef HAVE_SSL |
3612 | - if(ssl){ |
3613 | - SSL_shutdown(ssl); |
3614 | - SSL_free(ssl); |
3615 | - syslog(LOG_INFO,"INFO: SSL Socket Shutdown.\n"); |
3616 | - } |
3617 | -#endif |
3618 | - |
3619 | - return; |
3620 | - } |
3621 | - |
3622 | - /* we couldn't read the correct amount of data, so bail out */ |
3623 | - else if(bytes_to_recv!=sizeof(receive_packet)){ |
3624 | - |
3625 | - /* log error to syslog facility */ |
3626 | - syslog(LOG_ERR,"Data packet from client was too short, bailing out..."); |
3627 | - |
3628 | -#ifdef HAVE_SSL |
3629 | - if(ssl){ |
3630 | - SSL_shutdown(ssl); |
3631 | - SSL_free(ssl); |
3632 | - } |
3633 | -#endif |
3634 | - |
3635 | - return; |
3636 | - } |
3637 | - |
3638 | -#ifdef DEBUG |
3639 | - fp=fopen("/tmp/packet","w"); |
3640 | - if(fp){ |
3641 | - fwrite(&receive_packet,1,sizeof(receive_packet),fp); |
3642 | - fclose(fp); |
3643 | - } |
3644 | -#endif |
3645 | - |
3646 | - /* make sure the request is valid */ |
3647 | - if(validate_request(&receive_packet)==ERROR){ |
3648 | - |
3649 | - /* log an error */ |
3650 | - syslog(LOG_ERR,"Client request was invalid, bailing out..."); |
3651 | - |
3652 | - /* free memory */ |
3653 | - free(command_name); |
3654 | - command_name=NULL; |
3655 | - for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){ |
3656 | - free(macro_argv[x]); |
3657 | - macro_argv[x]=NULL; |
3658 | - } |
3659 | - |
3660 | -#ifdef HAVE_SSL |
3661 | - if(ssl){ |
3662 | - SSL_shutdown(ssl); |
3663 | - SSL_free(ssl); |
3664 | - } |
3665 | -#endif |
3666 | - |
3667 | - return; |
3668 | - } |
3669 | - |
3670 | - /* log info to syslog facility */ |
3671 | - if(debug==TRUE) |
3672 | - syslog(LOG_DEBUG,"Host is asking for command '%s' to be run...",receive_packet.buffer); |
3673 | - |
3674 | - /* disable connection alarm - a new alarm will be setup during my_system */ |
3675 | - alarm(0); |
3676 | - |
3677 | - /* if this is the version check command, just spew it out */ |
3678 | - if(!strcmp(command_name,NRPE_HELLO_COMMAND)){ |
3679 | - |
3680 | - snprintf(buffer,sizeof(buffer),"NRPE v%s",PROGRAM_VERSION); |
3681 | - buffer[sizeof(buffer)-1]='\x0'; |
3682 | - |
3683 | - /* log info to syslog facility */ |
3684 | - if(debug==TRUE) |
3685 | - syslog(LOG_DEBUG,"Response: %s",buffer); |
3686 | - |
3687 | - result=STATE_OK; |
3688 | - } |
3689 | - |
3690 | - /* find the command we're supposed to run */ |
3691 | - else{ |
3692 | - temp_command=find_command(command_name); |
3693 | - if(temp_command==NULL){ |
3694 | - |
3695 | - snprintf(buffer,sizeof(buffer),"NRPE: Command '%s' not defined",command_name); |
3696 | - buffer[sizeof(buffer)-1]='\x0'; |
3697 | - |
3698 | - /* log error to syslog facility */ |
3699 | - if(debug==TRUE) |
3700 | - syslog(LOG_DEBUG,"%s",buffer); |
3701 | - |
3702 | - result=STATE_CRITICAL; |
3703 | - } |
3704 | - |
3705 | - else{ |
3706 | - |
3707 | - /* process command line */ |
3708 | - if(command_prefix==NULL) |
3709 | - strncpy(raw_command,temp_command->command_line,sizeof(raw_command)-1); |
3710 | - else |
3711 | - snprintf(raw_command,sizeof(raw_command)-1,"%s %s",command_prefix,temp_command->command_line); |
3712 | - raw_command[sizeof(raw_command)-1]='\x0'; |
3713 | - process_macros(raw_command,processed_command,sizeof(processed_command)); |
3714 | - |
3715 | - /* log info to syslog facility */ |
3716 | - if(debug==TRUE) |
3717 | - syslog(LOG_DEBUG,"Running command: %s",processed_command); |
3718 | - |
3719 | - /* run the command */ |
3720 | - strcpy(buffer,""); |
3721 | - result=my_system(processed_command,command_timeout,&early_timeout,buffer,sizeof(buffer)); |
3722 | - |
3723 | - /* log debug info */ |
3724 | - if(debug==TRUE) |
3725 | - syslog(LOG_DEBUG,"Command completed with return code %d and output: %s",result,buffer); |
3726 | - |
3727 | - /* see if the command timed out */ |
3728 | - if(early_timeout==TRUE) |
3729 | - snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",command_timeout); |
3730 | - else if(!strcmp(buffer,"")) |
3731 | - snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n"); |
3732 | - |
3733 | - buffer[sizeof(buffer)-1]='\x0'; |
3734 | - |
3735 | - /* check return code bounds */ |
3736 | - if((result<0) || (result>3)){ |
3737 | - |
3738 | - /* log error to syslog facility */ |
3739 | - syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result); |
3740 | - |
3741 | - result=STATE_UNKNOWN; |
3742 | - } |
3743 | - } |
3744 | - } |
3745 | - |
3746 | - /* free memory */ |
3747 | - free(command_name); |
3748 | - command_name=NULL; |
3749 | - for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){ |
3750 | - free(macro_argv[x]); |
3751 | - macro_argv[x]=NULL; |
3752 | - } |
3753 | - |
3754 | - /* strip newline character from end of output buffer */ |
3755 | - if(buffer[strlen(buffer)-1]=='\n') |
3756 | - buffer[strlen(buffer)-1]='\x0'; |
3757 | - |
3758 | - /* clear the response packet buffer */ |
3759 | - bzero(&send_packet,sizeof(send_packet)); |
3760 | - |
3761 | - /* fill the packet with semi-random data */ |
3762 | - randomize_buffer((char *)&send_packet,sizeof(send_packet)); |
3763 | - |
3764 | - /* initialize response packet data */ |
3765 | - send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2); |
3766 | - send_packet.packet_type=(int16_t)htons(RESPONSE_PACKET); |
3767 | - send_packet.result_code=(int16_t)htons(result); |
3768 | - strncpy(&send_packet.buffer[0],buffer,MAX_PACKETBUFFER_LENGTH); |
3769 | - send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; |
3770 | - |
3771 | - /* calculate the crc 32 value of the packet */ |
3772 | - send_packet.crc32_value=(u_int32_t)0L; |
3773 | - calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet)); |
3774 | - send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32); |
3775 | - |
3776 | - |
3777 | - /***** ENCRYPT RESPONSE *****/ |
3778 | - |
3779 | - |
3780 | - /* send the response back to the client */ |
3781 | - bytes_to_send=sizeof(send_packet); |
3782 | - if(use_ssl==FALSE) |
3783 | - sendall(sock,(char *)&send_packet,&bytes_to_send); |
3784 | -#ifdef HAVE_SSL |
3785 | - else |
3786 | - SSL_write(ssl,&send_packet,bytes_to_send); |
3787 | -#endif |
3788 | - |
3789 | -#ifdef HAVE_SSL |
3790 | - if(ssl){ |
3791 | - SSL_shutdown(ssl); |
3792 | - SSL_free(ssl); |
3793 | - } |
3794 | -#endif |
3795 | - |
3796 | - /* log info to syslog facility */ |
3797 | - if(debug==TRUE) |
3798 | - syslog(LOG_DEBUG,"Return Code: %d, Output: %s",result,buffer); |
3799 | - |
3800 | - return; |
3801 | - } |
3802 | - |
3803 | - |
3804 | - |
3805 | -/* free all allocated memory */ |
3806 | -void free_memory(void){ |
3807 | - command *this_command; |
3808 | - command *next_command; |
3809 | - |
3810 | - /* free memory for the command list */ |
3811 | - this_command=command_list; |
3812 | - while(this_command!=NULL){ |
3813 | - next_command=this_command->next; |
3814 | - if(this_command->command_name) |
3815 | - free(this_command->command_name); |
3816 | - if(this_command->command_line) |
3817 | - free(this_command->command_line); |
3818 | - free(this_command); |
3819 | - this_command=next_command; |
3820 | - } |
3821 | - |
3822 | - command_list=NULL; |
3823 | - |
3824 | - return; |
3825 | - } |
3826 | - |
3827 | - |
3828 | - |
3829 | -/* executes a system command via popen(), but protects against timeouts */ |
3830 | -int my_system(char *command,int timeout,int *early_timeout,char *output,int output_length){ |
3831 | - pid_t pid; |
3832 | - int status; |
3833 | - int result; |
3834 | - extern int errno; |
3835 | - char buffer[MAX_INPUT_BUFFER]; |
3836 | - int fd[2]; |
3837 | - FILE *fp; |
3838 | - int bytes_read=0; |
3839 | - time_t start_time,end_time; |
3840 | - |
3841 | - /* initialize return variables */ |
3842 | - if(output!=NULL) |
3843 | - strcpy(output,""); |
3844 | - *early_timeout=FALSE; |
3845 | - |
3846 | - /* if no command was passed, return with no error */ |
3847 | - if(command==NULL) |
3848 | - return STATE_OK; |
3849 | - |
3850 | - /* create a pipe */ |
3851 | - pipe(fd); |
3852 | - |
3853 | - /* make the pipe non-blocking */ |
3854 | - fcntl(fd[0],F_SETFL,O_NONBLOCK); |
3855 | - fcntl(fd[1],F_SETFL,O_NONBLOCK); |
3856 | - |
3857 | - /* get the command start time */ |
3858 | - time(&start_time); |
3859 | - |
3860 | - /* fork */ |
3861 | - pid=fork(); |
3862 | - |
3863 | - /* return an error if we couldn't fork */ |
3864 | - if(pid==-1){ |
3865 | - |
3866 | - snprintf(buffer,sizeof(buffer)-1,"NRPE: Call to fork() failed\n"); |
3867 | - buffer[sizeof(buffer)-1]='\x0'; |
3868 | - |
3869 | - if(output!=NULL){ |
3870 | - strncpy(output,buffer,output_length-1); |
3871 | - output[output_length-1]='\x0'; |
3872 | - } |
3873 | - |
3874 | - /* close both ends of the pipe */ |
3875 | - close(fd[0]); |
3876 | - close(fd[1]); |
3877 | - |
3878 | - return STATE_UNKNOWN; |
3879 | - } |
3880 | - |
3881 | - /* execute the command in the child process */ |
3882 | - if(pid==0){ |
3883 | - |
3884 | - /* close pipe for reading */ |
3885 | - close(fd[0]); |
3886 | - |
3887 | - /* become process group leader */ |
3888 | - setpgid(0,0); |
3889 | - |
3890 | - /* trap commands that timeout */ |
3891 | - signal(SIGALRM,my_system_sighandler); |
3892 | - alarm(timeout); |
3893 | - |
3894 | - /* run the command */ |
3895 | - fp=popen(command,"r"); |
3896 | - |
3897 | - /* report an error if we couldn't run the command */ |
3898 | - if(fp==NULL){ |
3899 | - |
3900 | - strncpy(buffer,"NRPE: Call to popen() failed\n",sizeof(buffer)-1); |
3901 | - buffer[sizeof(buffer)-1]='\x0'; |
3902 | - |
3903 | - /* write the error back to the parent process */ |
3904 | - write(fd[1],buffer,strlen(buffer)+1); |
3905 | - |
3906 | - result=STATE_CRITICAL; |
3907 | - } |
3908 | - else{ |
3909 | - |
3910 | - /* read all lines of output - supports Nagios 3.x multiline output */ |
3911 | - while((bytes_read=fread(buffer,1,sizeof(buffer)-1,fp))>0){ |
3912 | - |
3913 | - /* write the output back to the parent process */ |
3914 | - write(fd[1],buffer,bytes_read); |
3915 | - } |
3916 | - |
3917 | - /* close the command and get termination status */ |
3918 | - status=pclose(fp); |
3919 | - |
3920 | - /* report an error if we couldn't close the command */ |
3921 | - if(status==-1) |
3922 | - result=STATE_CRITICAL; |
3923 | - /* report an error if child died due to signal (Klas Lindfors) */ |
3924 | - else if(!WIFEXITED(status)) |
3925 | - result=STATE_CRITICAL; |
3926 | - else |
3927 | - result=WEXITSTATUS(status); |
3928 | - } |
3929 | - |
3930 | - /* close pipe for writing */ |
3931 | - close(fd[1]); |
3932 | - |
3933 | - /* reset the alarm */ |
3934 | - alarm(0); |
3935 | - |
3936 | - /* return plugin exit code to parent process */ |
3937 | - exit(result); |
3938 | - } |
3939 | - |
3940 | - /* parent waits for child to finish executing command */ |
3941 | - else{ |
3942 | - |
3943 | - /* close pipe for writing */ |
3944 | - close(fd[1]); |
3945 | - |
3946 | - /* wait for child to exit */ |
3947 | - waitpid(pid,&status,0); |
3948 | - |
3949 | - /* get the end time for running the command */ |
3950 | - time(&end_time); |
3951 | - |
3952 | - /* get the exit code returned from the program */ |
3953 | - result=WEXITSTATUS(status); |
3954 | - |
3955 | - /* because of my idiotic idea of having UNKNOWN states be equivalent to -1, I must hack things a bit... */ |
3956 | - if(result==255) |
3957 | - result=STATE_UNKNOWN; |
3958 | - |
3959 | - /* check bounds on the return value */ |
3960 | - if(result<0 || result>3) |
3961 | - result=STATE_UNKNOWN; |
3962 | - |
3963 | - /* try and read the results from the command output (retry if we encountered a signal) */ |
3964 | - if(output!=NULL){ |
3965 | - do{ |
3966 | - bytes_read=read(fd[0], output, output_length-1); |
3967 | - }while (bytes_read==-1 && errno==EINTR); |
3968 | - |
3969 | - if(bytes_read==-1) |
3970 | - *output='\0'; |
3971 | - else |
3972 | - output[bytes_read]='\0'; |
3973 | - } |
3974 | - |
3975 | - /* if there was a critical return code and no output AND the command time exceeded the timeout thresholds, assume a timeout */ |
3976 | - if(result==STATE_CRITICAL && bytes_read==-1 && (end_time-start_time)>=timeout){ |
3977 | - *early_timeout=TRUE; |
3978 | - |
3979 | - /* send termination signal to child process group */ |
3980 | - kill((pid_t)(-pid),SIGTERM); |
3981 | - kill((pid_t)(-pid),SIGKILL); |
3982 | - } |
3983 | - |
3984 | - /* close the pipe for reading */ |
3985 | - close(fd[0]); |
3986 | - } |
3987 | - |
3988 | -#ifdef DEBUG |
3989 | - printf("my_system() end\n"); |
3990 | -#endif |
3991 | - |
3992 | - return result; |
3993 | - } |
3994 | - |
3995 | - |
3996 | - |
3997 | -/* handle timeouts when executing commands via my_system() */ |
3998 | -void my_system_sighandler(int sig){ |
3999 | - |
4000 | - /* force the child process to exit... */ |
4001 | - exit(STATE_CRITICAL); |
4002 | - } |
4003 | - |
4004 | - |
4005 | -/* handle errors where connection takes too long */ |
4006 | -void my_connection_sighandler(int sig) { |
4007 | - |
4008 | - syslog(LOG_ERR,"Connection has taken too long to establish. Exiting..."); |
4009 | - |
4010 | - exit(STATE_CRITICAL); |
4011 | - } |
4012 | - |
4013 | - |
4014 | -/* drops privileges */ |
4015 | -int drop_privileges(char *user, char *group){ |
4016 | - uid_t uid=-1; |
4017 | - gid_t gid=-1; |
4018 | - struct group *grp; |
4019 | - struct passwd *pw; |
4020 | - |
4021 | - /* set effective group ID */ |
4022 | - if(group!=NULL){ |
4023 | - |
4024 | - /* see if this is a group name */ |
4025 | - if(strspn(group,"0123456789")<strlen(group)){ |
4026 | - grp=(struct group *)getgrnam(group); |
4027 | - if(grp!=NULL) |
4028 | - gid=(gid_t)(grp->gr_gid); |
4029 | - else |
4030 | - syslog(LOG_ERR,"Warning: Could not get group entry for '%s'",group); |
4031 | - endgrent(); |
4032 | - } |
4033 | - |
4034 | - /* else we were passed the GID */ |
4035 | - else |
4036 | - gid=(gid_t)atoi(group); |
4037 | - |
4038 | - /* set effective group ID if other than current EGID */ |
4039 | - if(gid!=getegid()){ |
4040 | - |
4041 | - if(setgid(gid)==-1) |
4042 | - syslog(LOG_ERR,"Warning: Could not set effective GID=%d",(int)gid); |
4043 | - } |
4044 | - } |
4045 | - |
4046 | - |
4047 | - /* set effective user ID */ |
4048 | - if(user!=NULL){ |
4049 | - |
4050 | - /* see if this is a user name */ |
4051 | - if(strspn(user,"0123456789")<strlen(user)){ |
4052 | - pw=(struct passwd *)getpwnam(user); |
4053 | - if(pw!=NULL) |
4054 | - uid=(uid_t)(pw->pw_uid); |
4055 | - else |
4056 | - syslog(LOG_ERR,"Warning: Could not get passwd entry for '%s'",user); |
4057 | - endpwent(); |
4058 | - } |
4059 | - |
4060 | - /* else we were passed the UID */ |
4061 | - else |
4062 | - uid=(uid_t)atoi(user); |
4063 | - |
4064 | - /* set effective user ID if other than current EUID */ |
4065 | - if(uid!=geteuid()){ |
4066 | - |
4067 | -#ifdef HAVE_INITGROUPS |
4068 | - /* initialize supplementary groups */ |
4069 | - if(initgroups(user,gid)==-1){ |
4070 | - if(errno==EPERM) |
4071 | - syslog(LOG_ERR,"Warning: Unable to change supplementary groups using initgroups()"); |
4072 | - else{ |
4073 | - syslog(LOG_ERR,"Warning: Possibly root user failed dropping privileges with initgroups()"); |
4074 | - return ERROR; |
4075 | - } |
4076 | - } |
4077 | -#endif |
4078 | - |
4079 | - if(setuid(uid)==-1) |
4080 | - syslog(LOG_ERR,"Warning: Could not set effective UID=%d",(int)uid); |
4081 | - } |
4082 | - } |
4083 | - |
4084 | - return OK; |
4085 | - } |
4086 | - |
4087 | - |
4088 | -/* write an optional pid file */ |
4089 | -int write_pid_file(void){ |
4090 | - int fd; |
4091 | - int result=0; |
4092 | - pid_t pid=0; |
4093 | - char pbuf[16]; |
4094 | - |
4095 | - /* no pid file was specified */ |
4096 | - if(pid_file==NULL) |
4097 | - return OK; |
4098 | - |
4099 | - /* read existing pid file */ |
4100 | - if((fd=open(pid_file,O_RDONLY))>=0){ |
4101 | - |
4102 | - result=read(fd,pbuf,(sizeof pbuf)-1); |
4103 | - |
4104 | - close(fd); |
4105 | - |
4106 | - if(result>0){ |
4107 | - |
4108 | - pbuf[result]='\x0'; |
4109 | - pid=(pid_t)atoi(pbuf); |
4110 | - |
4111 | - /* if previous process is no longer running running, remove the old pid file */ |
4112 | - if(pid && (pid==getpid() || kill(pid,0)<0)) |
4113 | - unlink(pid_file); |
4114 | - |
4115 | - /* previous process is still running */ |
4116 | - else{ |
4117 | - syslog(LOG_ERR,"There's already an NRPE server running (PID %lu). Bailing out...",(unsigned long)pid); |
4118 | - return ERROR; |
4119 | - } |
4120 | - } |
4121 | - } |
4122 | - |
4123 | - /* write new pid file */ |
4124 | - if((fd=open(pid_file,O_WRONLY | O_CREAT,0644))>=0){ |
4125 | - sprintf(pbuf,"%d\n",(int)getpid()); |
4126 | - write(fd,pbuf,strlen(pbuf)); |
4127 | - close(fd); |
4128 | - wrote_pid_file=TRUE; |
4129 | - } |
4130 | - else{ |
4131 | - syslog(LOG_ERR,"Cannot write to pidfile '%s' - check your privileges.",pid_file); |
4132 | - } |
4133 | - |
4134 | - return OK; |
4135 | - } |
4136 | - |
4137 | - |
4138 | - |
4139 | -/* remove pid file */ |
4140 | -int remove_pid_file(void){ |
4141 | - |
4142 | - /* no pid file was specified */ |
4143 | - if(pid_file==NULL) |
4144 | - return OK; |
4145 | - |
4146 | - /* pid file was not written */ |
4147 | - if(wrote_pid_file==FALSE) |
4148 | - return OK; |
4149 | - |
4150 | - /* remove existing pid file */ |
4151 | - if(unlink(pid_file)==-1){ |
4152 | - syslog(LOG_ERR,"Cannot remove pidfile '%s' - check your privileges.",pid_file); |
4153 | - return ERROR; |
4154 | - } |
4155 | - |
4156 | - return OK; |
4157 | - } |
4158 | - |
4159 | - |
4160 | - |
4161 | -/* bail if daemon is running as root */ |
4162 | -int check_privileges(void){ |
4163 | - uid_t uid=-1; |
4164 | - gid_t gid=-1; |
4165 | - |
4166 | - uid=geteuid(); |
4167 | - gid=getegid(); |
4168 | - |
4169 | - if(uid==0 || gid==0){ |
4170 | - syslog(LOG_ERR,"Error: NRPE daemon cannot be run as user/group root!"); |
4171 | - exit(STATE_CRITICAL); |
4172 | - } |
4173 | - |
4174 | - return OK; |
4175 | - } |
4176 | - |
4177 | - |
4178 | - |
4179 | -/* handle signals (parent process) */ |
4180 | -void sighandler(int sig){ |
4181 | - static char *sigs[]={"EXIT","HUP","INT","QUIT","ILL","TRAP","ABRT","BUS","FPE","KILL","USR1","SEGV","USR2","PIPE","ALRM","TERM","STKFLT","CHLD","CONT","STOP","TSTP","TTIN","TTOU","URG","XCPU","XFSZ","VTALRM","PROF","WINCH","IO","PWR","UNUSED","ZERR","DEBUG",(char *)NULL}; |
4182 | - int i; |
4183 | - |
4184 | - if(sig<0) |
4185 | - sig=-sig; |
4186 | - |
4187 | - for(i=0;sigs[i]!=(char *)NULL;i++); |
4188 | - |
4189 | - sig%=i; |
4190 | - |
4191 | - /* we received a SIGHUP, so restart... */ |
4192 | - if(sig==SIGHUP){ |
4193 | - |
4194 | - sigrestart=TRUE; |
4195 | - |
4196 | - syslog(LOG_NOTICE,"Caught SIGHUP - restarting...\n"); |
4197 | - } |
4198 | - |
4199 | - /* else begin shutting down... */ |
4200 | - if(sig==SIGTERM){ |
4201 | - |
4202 | - /* if shutdown is already true, we're in a signal trap loop! */ |
4203 | - if(sigshutdown==TRUE) |
4204 | - exit(STATE_CRITICAL); |
4205 | - |
4206 | - sigshutdown=TRUE; |
4207 | - |
4208 | - syslog(LOG_NOTICE,"Caught SIG%s - shutting down...\n",sigs[sig]); |
4209 | - } |
4210 | - |
4211 | - return; |
4212 | - } |
4213 | - |
4214 | - |
4215 | - |
4216 | -/* handle signals (child processes) */ |
4217 | -void child_sighandler(int sig){ |
4218 | - |
4219 | - /* free all memory we allocated */ |
4220 | - free_memory(); |
4221 | - |
4222 | - /* terminate */ |
4223 | - exit(0); |
4224 | - |
4225 | - /* so the compiler doesn't complain... */ |
4226 | - return; |
4227 | - } |
4228 | - |
4229 | - |
4230 | - |
4231 | -/* tests whether or not a client request is valid */ |
4232 | -int validate_request(packet *pkt){ |
4233 | - u_int32_t packet_crc32; |
4234 | - u_int32_t calculated_crc32; |
4235 | - char *ptr; |
4236 | -#ifdef ENABLE_COMMAND_ARGUMENTS |
4237 | - int x; |
4238 | -#endif |
4239 | - |
4240 | - |
4241 | - /***** DECRYPT REQUEST ******/ |
4242 | - |
4243 | - |
4244 | - /* check the crc 32 value */ |
4245 | - packet_crc32=ntohl(pkt->crc32_value); |
4246 | - pkt->crc32_value=0L; |
4247 | - calculated_crc32=calculate_crc32((char *)pkt,sizeof(packet)); |
4248 | - if(packet_crc32!=calculated_crc32){ |
4249 | - syslog(LOG_ERR,"Error: Request packet had invalid CRC32."); |
4250 | - return ERROR; |
4251 | - } |
4252 | - |
4253 | - /* make sure this is the right type of packet */ |
4254 | - if(ntohs(pkt->packet_type)!=QUERY_PACKET || ntohs(pkt->packet_version)!=NRPE_PACKET_VERSION_2){ |
4255 | - syslog(LOG_ERR,"Error: Request packet type/version was invalid!"); |
4256 | - return ERROR; |
4257 | - } |
4258 | - |
4259 | - /* make sure buffer is terminated */ |
4260 | - pkt->buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0'; |
4261 | - |
4262 | - /* client must send some kind of request */ |
4263 | - if(!strcmp(pkt->buffer,"")){ |
4264 | - syslog(LOG_ERR,"Error: Request contained no query!"); |
4265 | - return ERROR; |
4266 | - } |
4267 | - |
4268 | - /* make sure request doesn't contain nasties */ |
4269 | - if(contains_nasty_metachars(pkt->buffer)==TRUE){ |
4270 | - syslog(LOG_ERR,"Error: Request contained illegal metachars!"); |
4271 | - return ERROR; |
4272 | - } |
4273 | - |
4274 | - /* make sure the request doesn't contain arguments */ |
4275 | - if(strchr(pkt->buffer,'!')){ |
4276 | -#ifdef ENABLE_COMMAND_ARGUMENTS |
4277 | - if(allow_arguments==FALSE){ |
4278 | - syslog(LOG_ERR,"Error: Request contained command arguments, but argument option is not enabled!"); |
4279 | - return ERROR; |
4280 | - } |
4281 | -#else |
4282 | - syslog(LOG_ERR,"Error: Request contained command arguments!"); |
4283 | - return ERROR; |
4284 | -#endif |
4285 | - } |
4286 | - |
4287 | - /* get command name */ |
4288 | -#ifdef ENABLE_COMMAND_ARGUMENTS |
4289 | - ptr=strtok(pkt->buffer,"!"); |
4290 | -#else |
4291 | - ptr=pkt->buffer; |
4292 | -#endif |
4293 | - command_name=strdup(ptr); |
4294 | - if(command_name==NULL){ |
4295 | - syslog(LOG_ERR,"Error: Memory allocation failed"); |
4296 | - return ERROR; |
4297 | - } |
4298 | - |
4299 | -#ifdef ENABLE_COMMAND_ARGUMENTS |
4300 | - /* get command arguments */ |
4301 | - if(allow_arguments==TRUE){ |
4302 | - |
4303 | - for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){ |
4304 | - ptr=strtok(NULL,"!"); |
4305 | - if(ptr==NULL) |
4306 | - break; |
4307 | - macro_argv[x]=strdup(ptr); |
4308 | - if(macro_argv[x]==NULL){ |
4309 | - syslog(LOG_ERR,"Error: Memory allocation failed"); |
4310 | - return ERROR; |
4311 | - } |
4312 | - if(!strcmp(macro_argv[x],"")){ |
4313 | - syslog(LOG_ERR,"Error: Request contained an empty command argument"); |
4314 | - return ERROR; |
4315 | - } |
4316 | - } |
4317 | - } |
4318 | -#endif |
4319 | - |
4320 | - return OK; |
4321 | - } |
4322 | - |
4323 | - |
4324 | - |
4325 | -/* tests whether a buffer contains illegal metachars */ |
4326 | -int contains_nasty_metachars(char *str){ |
4327 | - int result; |
4328 | - |
4329 | - if(str==NULL) |
4330 | - return FALSE; |
4331 | - |
4332 | - result=strcspn(str,NASTY_METACHARS); |
4333 | - if(result!=strlen(str)) |
4334 | - return TRUE; |
4335 | - |
4336 | - return FALSE; |
4337 | - } |
4338 | - |
4339 | - |
4340 | - |
4341 | -/* replace macros in buffer */ |
4342 | -int process_macros(char *input_buffer,char *output_buffer,int buffer_length){ |
4343 | - char *temp_buffer; |
4344 | - int in_macro; |
4345 | - int arg_index=0; |
4346 | - char *selected_macro=NULL; |
4347 | - |
4348 | - strcpy(output_buffer,""); |
4349 | - |
4350 | - in_macro=FALSE; |
4351 | - |
4352 | - for(temp_buffer=my_strsep(&input_buffer,"$");temp_buffer!=NULL;temp_buffer=my_strsep(&input_buffer,"$")){ |
4353 | - |
4354 | - selected_macro=NULL; |
4355 | - |
4356 | - if(in_macro==FALSE){ |
4357 | - if(strlen(output_buffer)+strlen(temp_buffer)<buffer_length-1){ |
4358 | - strncat(output_buffer,temp_buffer,buffer_length-strlen(output_buffer)-1); |
4359 | - output_buffer[buffer_length-1]='\x0'; |
4360 | - } |
4361 | - in_macro=TRUE; |
4362 | - } |
4363 | - else{ |
4364 | - |
4365 | - if(strlen(output_buffer)+strlen(temp_buffer)<buffer_length-1){ |
4366 | - |
4367 | - /* argument macro */ |
4368 | - if(strstr(temp_buffer,"ARG")==temp_buffer){ |
4369 | - arg_index=atoi(temp_buffer+3); |
4370 | - if(arg_index>=1 && arg_index<=MAX_COMMAND_ARGUMENTS) |
4371 | - selected_macro=macro_argv[arg_index-1]; |
4372 | - } |
4373 | - |
4374 | - /* an escaped $ is done by specifying two $$ next to each other */ |
4375 | - else if(!strcmp(temp_buffer,"")){ |
4376 | - strncat(output_buffer,"$",buffer_length-strlen(output_buffer)-1); |
4377 | - } |
4378 | - |
4379 | - /* a non-macro, just some user-defined string between two $s */ |
4380 | - else{ |
4381 | - strncat(output_buffer,"$",buffer_length-strlen(output_buffer)-1); |
4382 | - output_buffer[buffer_length-1]='\x0'; |
4383 | - strncat(output_buffer,temp_buffer,buffer_length-strlen(output_buffer)-1); |
4384 | - output_buffer[buffer_length-1]='\x0'; |
4385 | - strncat(output_buffer,"$",buffer_length-strlen(output_buffer)-1); |
4386 | - } |
4387 | - |
4388 | - |
4389 | - /* insert macro */ |
4390 | - if(selected_macro!=NULL) |
4391 | - strncat(output_buffer,(selected_macro==NULL)?"":selected_macro,buffer_length-strlen(output_buffer)-1); |
4392 | - |
4393 | - output_buffer[buffer_length-1]='\x0'; |
4394 | - } |
4395 | - |
4396 | - in_macro=FALSE; |
4397 | - } |
4398 | - } |
4399 | - |
4400 | - return OK; |
4401 | - } |
4402 | - |
4403 | - |
4404 | - |
4405 | -/* process command line arguments */ |
4406 | -int process_arguments(int argc, char **argv){ |
4407 | - char optchars[MAX_INPUT_BUFFER]; |
4408 | - int c=1; |
4409 | - int have_mode=FALSE; |
4410 | - |
4411 | -#ifdef HAVE_GETOPT_LONG |
4412 | - int option_index=0; |
4413 | - static struct option long_options[]={ |
4414 | - {"config", required_argument, 0, 'c'}, |
4415 | - {"inetd", no_argument, 0, 'i'}, |
4416 | - {"daemon", no_argument, 0, 'd'}, |
4417 | - {"no-ssl", no_argument, 0, 'n'}, |
4418 | - {"help", no_argument, 0, 'h'}, |
4419 | - {"license", no_argument, 0, 'l'}, |
4420 | - {0, 0, 0, 0} |
4421 | - }; |
4422 | -#endif |
4423 | - |
4424 | - /* no options were supplied */ |
4425 | - if(argc<2) |
4426 | - return ERROR; |
4427 | - |
4428 | - snprintf(optchars,MAX_INPUT_BUFFER,"c:hVldin"); |
4429 | - |
4430 | - while(1){ |
4431 | -#ifdef HAVE_GETOPT_LONG |
4432 | - c=getopt_long(argc,argv,optchars,long_options,&option_index); |
4433 | -#else |
4434 | - c=getopt(argc,argv,optchars); |
4435 | -#endif |
4436 | - if(c==-1 || c==EOF) |
4437 | - break; |
4438 | - |
4439 | - /* process all arguments */ |
4440 | - switch(c){ |
4441 | - |
4442 | - case '?': |
4443 | - case 'h': |
4444 | - show_help=TRUE; |
4445 | - break; |
4446 | - case 'V': |
4447 | - show_version=TRUE; |
4448 | - break; |
4449 | - case 'l': |
4450 | - show_license=TRUE; |
4451 | - break; |
4452 | - case 'c': |
4453 | - strncpy(config_file,optarg,sizeof(config_file)); |
4454 | - config_file[sizeof(config_file)-1]='\x0'; |
4455 | - break; |
4456 | - case 'd': |
4457 | - use_inetd=FALSE; |
4458 | - have_mode=TRUE; |
4459 | - break; |
4460 | - case 'i': |
4461 | - use_inetd=TRUE; |
4462 | - have_mode=TRUE; |
4463 | - break; |
4464 | - case 'n': |
4465 | - use_ssl=FALSE; |
4466 | - break; |
4467 | - default: |
4468 | - return ERROR; |
4469 | - break; |
4470 | - } |
4471 | - } |
4472 | - |
4473 | - /* bail if we didn't get required args */ |
4474 | - if(have_mode==FALSE) |
4475 | - return ERROR; |
4476 | - |
4477 | - return OK; |
4478 | - } |
4479 | - |
4480 | +/******************************************************************************* |
4481 | + * |
4482 | + * NRPE.C - Nagios Remote Plugin Executor |
4483 | + * Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org) |
4484 | + * License: GPL |
4485 | + * |
4486 | + * Last Modified: 11-11-2011 |
4487 | + * |
4488 | + * Command line: nrpe -c <config_file> [--inetd | --daemon] |
4489 | + * |
4490 | + * Description: |
4491 | + * |
4492 | + * This program is designed to run as a background process and |
4493 | + * handle incoming requests (from the host running Nagios) for |
4494 | + * plugin execution. It is useful for running "local" plugins |
4495 | + * such as check_users, check_load, check_disk, etc. without |
4496 | + * having to use rsh or ssh. |
4497 | + * |
4498 | + ******************************************************************************/ |
4499 | + |
4500 | +/* |
4501 | + * 08-10-2011 IPv4 subnetworks support added. |
4502 | + * Main change in nrpe.c is that is_an_allowed_host() moved to acl.c. |
4503 | + * now allowed_hosts is parsed by parse_allowed_hosts() from acl.c. |
4504 | + */ |
4505 | + |
4506 | +#include "../include/common.h" |
4507 | +#include "../include/config.h" |
4508 | +#include "../include/nrpe.h" |
4509 | +#include "../include/utils.h" |
4510 | +#include "../include/acl.h" |
4511 | + |
4512 | +#ifdef HAVE_SSL |
4513 | +#include "../include/dh.h" |
4514 | +#endif |
4515 | + |
4516 | +#ifdef HAVE_LIBWRAP |
4517 | +int allow_severity=LOG_INFO; |
4518 | +int deny_severity=LOG_WARNING; |
4519 | +#endif |
4520 | + |
4521 | +#ifdef HAVE_SSL |
4522 | +SSL_METHOD *meth; |
4523 | +SSL_CTX *ctx; |
4524 | +int use_ssl=TRUE; |
4525 | +#else |
4526 | +int use_ssl=FALSE; |
4527 | +#endif |
4528 | + |
4529 | +#define DEFAULT_COMMAND_TIMEOUT 60 /* default timeout for execution of plugins */ |
4530 | +#define MAXFD 64 |
4531 | +#define NASTY_METACHARS "|`&><'\"\\[]{};" |
4532 | + |
4533 | +char *command_name=NULL; |
4534 | +char *macro_argv[MAX_COMMAND_ARGUMENTS]; |
4535 | + |
4536 | +char config_file[MAX_INPUT_BUFFER]="nrpe.cfg"; |
4537 | +int log_facility=LOG_DAEMON; |
4538 | +int server_port=DEFAULT_SERVER_PORT; |
4539 | +char server_address[16]="0.0.0.0"; |
4540 | +int socket_timeout=DEFAULT_SOCKET_TIMEOUT; |
4541 | +int command_timeout=DEFAULT_COMMAND_TIMEOUT; |
4542 | +int connection_timeout=DEFAULT_CONNECTION_TIMEOUT; |
4543 | +char *command_prefix=NULL; |
4544 | + |
4545 | +command *command_list=NULL; |
4546 | + |
4547 | +char *nrpe_user=NULL; |
4548 | +char *nrpe_group=NULL; |
4549 | + |
4550 | +char *allowed_hosts=NULL; |
4551 | + |
4552 | +char *pid_file=NULL; |
4553 | +int wrote_pid_file=FALSE; |
4554 | + |
4555 | +int allow_arguments=FALSE; |
4556 | + |
4557 | +int allow_weak_random_seed=FALSE; |
4558 | + |
4559 | +int sigrestart=FALSE; |
4560 | +int sigshutdown=FALSE; |
4561 | + |
4562 | +int show_help=FALSE; |
4563 | +int show_license=FALSE; |
4564 | +int show_version=FALSE; |
4565 | +int use_inetd=TRUE; |
4566 | +int debug=FALSE; |
4567 | + |
4568 | + |
4569 | + |
4570 | + |
4571 | +int main(int argc, char **argv){ |
4572 | + int result=OK; |
4573 | + int x; |
4574 | + char buffer[MAX_INPUT_BUFFER]; |
4575 | + char *env_string=NULL; |
4576 | +#ifdef HAVE_SSL |
4577 | + DH *dh; |
4578 | + char seedfile[FILENAME_MAX]; |
4579 | + int i,c; |
4580 | +#endif |
4581 | + |
4582 | + /* set some environment variables */ |
4583 | + asprintf(&env_string,"NRPE_MULTILINESUPPORT=1"); |
4584 | + putenv(env_string); |
4585 | + asprintf(&env_string,"NRPE_PROGRAMVERSION=%s",PROGRAM_VERSION); |
4586 | + putenv(env_string); |
4587 | + |
4588 | + /* process command-line args */ |
4589 | + result=process_arguments(argc,argv); |
4590 | + |
4591 | + if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){ |
4592 | + |
4593 | + printf("\n"); |
4594 | + printf("NRPE - Nagios Remote Plugin Executor\n"); |
4595 | + printf("Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)\n"); |
4596 | + printf("Version: %s\n",PROGRAM_VERSION); |
4597 | + printf("Last Modified: %s\n",MODIFICATION_DATE); |
4598 | + printf("License: GPL v2 with exemptions (-l for more info)\n"); |
4599 | +#ifdef HAVE_SSL |
4600 | + printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n"); |
4601 | +#endif |
4602 | +#ifdef HAVE_LIBWRAP |
4603 | + printf("TCP Wrappers Available\n"); |
4604 | +#endif |
4605 | + printf("\n"); |
4606 | +#ifdef ENABLE_COMMAND_ARGUMENTS |
4607 | + printf("***************************************************************\n"); |
4608 | + printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n"); |
4609 | + printf("** Read the NRPE SECURITY file for more information **\n"); |
4610 | + printf("***************************************************************\n"); |
4611 | + printf("\n"); |
4612 | +#endif |
4613 | +#ifndef HAVE_LIBWRAP |
4614 | + printf("***************************************************************\n"); |
4615 | + printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE! **\n"); |
4616 | + printf("** Read the NRPE SECURITY file for more information **\n"); |
4617 | + printf("***************************************************************\n"); |
4618 | + printf("\n"); |
4619 | +#endif |
4620 | + } |
4621 | + |
4622 | + if(show_license==TRUE) |
4623 | + display_license(); |
4624 | + |
4625 | + else if(result!=OK || show_help==TRUE){ |
4626 | + |
4627 | + printf("Usage: nrpe [-n] -c <config_file> <mode>\n"); |
4628 | + printf("\n"); |
4629 | + printf("Options:\n"); |
4630 | + printf(" -n = Do not use SSL\n"); |
4631 | + printf(" <config_file> = Name of config file to use\n"); |
4632 | + printf(" <mode> = One of the following two operating modes:\n"); |
4633 | + printf(" -i = Run as a service under inetd or xinetd\n"); |
4634 | + printf(" -d = Run as a standalone daemon\n"); |
4635 | + printf("\n"); |
4636 | + printf("Notes:\n"); |
4637 | + printf("This program is designed to process requests from the check_nrpe\n"); |
4638 | + printf("plugin on the host(s) running Nagios. It can run as a service\n"); |
4639 | + printf("under inetd or xinetd (read the docs for info on this), or as a\n"); |
4640 | + printf("standalone daemon. Once a request is received from an authorized\n"); |
4641 | + printf("host, NRPE will execute the command/plugin (as defined in the\n"); |
4642 | + printf("config file) and return the plugin output and return code to the\n"); |
4643 | + printf("check_nrpe plugin.\n"); |
4644 | + printf("\n"); |
4645 | + } |
4646 | + |
4647 | + if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE) |
4648 | + exit(STATE_UNKNOWN); |
4649 | + |
4650 | + |
4651 | + /* open a connection to the syslog facility */ |
4652 | + /* facility name may be overridden later */ |
4653 | + get_log_facility(NRPE_LOG_FACILITY); |
4654 | + openlog("nrpe",LOG_PID,log_facility); |
4655 | + |
4656 | + /* make sure the config file uses an absolute path */ |
4657 | + if(config_file[0]!='/'){ |
4658 | + |
4659 | + /* save the name of the config file */ |
4660 | + strncpy(buffer,config_file,sizeof(buffer)); |
4661 | + buffer[sizeof(buffer)-1]='\x0'; |
4662 | + |
4663 | + /* get absolute path of current working directory */ |
4664 | + strcpy(config_file,""); |
4665 | + getcwd(config_file,sizeof(config_file)); |
4666 | + |
4667 | + /* append a forward slash */ |
4668 | + strncat(config_file,"/",sizeof(config_file)-2); |
4669 | + config_file[sizeof(config_file)-1]='\x0'; |
4670 | + |
4671 | + /* append the config file to the path */ |
4672 | + strncat(config_file,buffer,sizeof(config_file)-strlen(config_file)-1); |
4673 | + config_file[sizeof(config_file)-1]='\x0'; |
4674 | + } |
4675 | + |
4676 | + /* read the config file */ |
4677 | + result=read_config_file(config_file); |
4678 | + |
4679 | + /* exit if there are errors... */ |
4680 | + if(result==ERROR){ |
4681 | + syslog(LOG_ERR,"Config file '%s' contained errors, aborting...",config_file); |
4682 | + return STATE_CRITICAL; |
4683 | + } |
4684 | + |
4685 | + /* generate the CRC 32 table */ |
4686 | + generate_crc32_table(); |
4687 | + |
4688 | + /* initialize macros */ |
4689 | + for(x=0;x<MAX_COMMAND_ARGUMENTS;x++) |
4690 | + macro_argv[x]=NULL; |
4691 | + |
4692 | +#ifdef HAVE_SSL |
4693 | + /* initialize SSL */ |
4694 | + if(use_ssl==TRUE){ |
4695 | + SSL_library_init(); |
4696 | + SSLeay_add_ssl_algorithms(); |
4697 | + meth=SSLv23_server_method(); |
4698 | + SSL_load_error_strings(); |
4699 | + |
4700 | + /* use week random seed if necessary */ |
4701 | + if(allow_weak_random_seed && (RAND_status()==0)){ |
4702 | + |
4703 | + if(RAND_file_name(seedfile,sizeof(seedfile)-1)) |
4704 | + if(RAND_load_file(seedfile,-1)) |
4705 | + RAND_write_file(seedfile); |
4706 | + |
4707 | + if(RAND_status()==0){ |
4708 | + syslog(LOG_ERR,"Warning: SSL/TLS uses a weak random seed which is highly discouraged"); |
4709 | + srand(time(NULL)); |
4710 | + for(i=0;i<500 && RAND_status()==0;i++){ |
4711 | + for(c=0;c<sizeof(seedfile);c+=sizeof(int)){ |
4712 | + *((int *)(seedfile+c))=rand(); |
4713 | + } |
4714 | + RAND_seed(seedfile,sizeof(seedfile)); |
4715 | + } |
4716 | + } |
4717 | + } |
4718 | + |
4719 | + if((ctx=SSL_CTX_new(meth))==NULL){ |
4720 | + syslog(LOG_ERR,"Error: could not create SSL context.\n"); |
4721 | + exit(STATE_CRITICAL); |
4722 | + } |
4723 | + |
4724 | + /* ADDED 01/19/2004 */ |
4725 | + /* use only TLSv1 protocol */ |
4726 | + SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); |
4727 | + |
4728 | + /* use anonymous DH ciphers */ |
4729 | + SSL_CTX_set_cipher_list(ctx,"ADH"); |
4730 | + dh=get_dh512(); |
4731 | + SSL_CTX_set_tmp_dh(ctx,dh); |
4732 | + DH_free(dh); |
4733 | + if(debug==TRUE) |
4734 | + syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted."); |
4735 | + } |
4736 | + else{ |
4737 | + if(debug==TRUE) |
4738 | + syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED."); |
4739 | + } |
4740 | +#endif |
4741 | + |
4742 | + /* if we're running under inetd... */ |
4743 | + if(use_inetd==TRUE){ |
4744 | + |
4745 | + /* make sure we're not root */ |
4746 | + check_privileges(); |
4747 | + |
4748 | + /* redirect STDERR to /dev/null */ |
4749 | + close(2); |
4750 | + open("/dev/null",O_WRONLY); |
4751 | + |
4752 | + /* handle the connection */ |
4753 | + handle_connection(0); |
4754 | + } |
4755 | + |
4756 | + /* else daemonize and start listening for requests... */ |
4757 | + else if(fork()==0){ |
4758 | + |
4759 | + /* we're a daemon - set up a new process group */ |
4760 | + setsid(); |
4761 | + |
4762 | + /* close standard file descriptors */ |
4763 | + close(0); |
4764 | + close(1); |
4765 | + close(2); |
4766 | + |
4767 | + /* redirect standard descriptors to /dev/null */ |
4768 | + open("/dev/null",O_RDONLY); |
4769 | + open("/dev/null",O_WRONLY); |
4770 | + open("/dev/null",O_WRONLY); |
4771 | + |
4772 | + chdir("/"); |
4773 | + /*umask(0);*/ |
4774 | + |
4775 | + /* handle signals */ |
4776 | + signal(SIGQUIT,sighandler); |
4777 | + signal(SIGTERM,sighandler); |
4778 | + signal(SIGHUP,sighandler); |
4779 | + |
4780 | + /* log info to syslog facility */ |
4781 | + syslog(LOG_NOTICE,"Starting up daemon"); |
4782 | + |
4783 | + /* write pid file */ |
4784 | + if(write_pid_file()==ERROR) |
4785 | + return STATE_CRITICAL; |
4786 | + |
4787 | + /* drop privileges */ |
4788 | + drop_privileges(nrpe_user,nrpe_group); |
4789 | + |
4790 | + /* make sure we're not root */ |
4791 | + check_privileges(); |
4792 | + |
4793 | + do{ |
4794 | + |
4795 | + /* reset flags */ |
4796 | + sigrestart=FALSE; |
4797 | + sigshutdown=FALSE; |
4798 | + |
4799 | + /* wait for connections */ |
4800 | + wait_for_connections(); |
4801 | + |
4802 | + /* free all memory we allocated */ |
4803 | + free_memory(); |
4804 | + |
4805 | + if(sigrestart==TRUE){ |
4806 | + |
4807 | + /* read the config file */ |
4808 | + result=read_config_file(config_file); |
4809 | + |
4810 | + /* exit if there are errors... */ |
4811 | + if(result==ERROR){ |
4812 | + syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file); |
4813 | + return STATE_CRITICAL; |
4814 | + } |
4815 | + } |
4816 | + |
4817 | + }while(sigrestart==TRUE && sigshutdown==FALSE); |
4818 | + |
4819 | + /* remove pid file */ |
4820 | + remove_pid_file(); |
4821 | + |
4822 | + syslog(LOG_NOTICE,"Daemon shutdown\n"); |
4823 | + } |
4824 | + |
4825 | +#ifdef HAVE_SSL |
4826 | + if(use_ssl==TRUE) |
4827 | + SSL_CTX_free(ctx); |
4828 | +#endif |
4829 | + |
4830 | + /* We are now running in daemon mode, or the connection handed over by inetd has |
4831 | + been completed, so the parent process exits */ |
4832 | + return STATE_OK; |
4833 | + } |
4834 | + |
4835 | + |
4836 | + |
4837 | + |
4838 | +/* read in the configuration file */ |
4839 | +int read_config_file(char *filename){ |
4840 | + FILE *fp; |
4841 | + char config_file[MAX_FILENAME_LENGTH]; |
4842 | + char input_buffer[MAX_INPUT_BUFFER]; |
4843 | + char *input_line; |
4844 | + char *temp_buffer; |
4845 | + char *varname; |
4846 | + char *varvalue; |
4847 | + int line=0; |
4848 | + int len=0; |
4849 | + int x=0; |
4850 | + |
4851 | + |
4852 | + /* open the config file for reading */ |
4853 | + fp=fopen(filename,"r"); |
4854 | + |
4855 | + /* exit if we couldn't open the config file */ |
4856 | + if(fp==NULL){ |
4857 | + syslog(LOG_ERR,"Unable to open config file '%s' for reading\n",filename); |
4858 | + return ERROR; |
4859 | + } |
4860 | + |
4861 | + while(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){ |
4862 | + |
4863 | + line++; |
4864 | + input_line=input_buffer; |
4865 | + |
4866 | + /* skip leading whitespace */ |
4867 | + while(isspace(*input_line)) |
4868 | + ++input_line; |
4869 | + |
4870 | + /* trim trailing whitespace */ |
4871 | + len=strlen(input_line); |
4872 | + for(x=len-1;x>=0;x--){ |
4873 | + if(isspace(input_line[x])) |
4874 | + input_line[x]='\x0'; |
4875 | + else |
4876 | + break; |
4877 | + } |
4878 | + |
4879 | + /* skip comments and blank lines */ |
4880 | + if(input_line[0]=='#') |
4881 | + continue; |
4882 | + if(input_line[0]=='\x0') |
4883 | + continue; |
4884 | + if(input_line[0]=='\n') |
4885 | + continue; |
4886 | + |
4887 | + /* get the variable name */ |
4888 | + varname=strtok(input_line,"="); |
4889 | + if(varname==NULL){ |
4890 | + syslog(LOG_ERR,"No variable name specified in config file '%s' - Line %d\n",filename,line); |
4891 | + return ERROR; |
4892 | + } |
4893 | + |
4894 | + /* get the variable value */ |
4895 | + varvalue=strtok(NULL,"\n"); |
4896 | + if(varvalue==NULL){ |
4897 | + syslog(LOG_ERR,"No variable value specified in config file '%s' - Line %d\n",filename,line); |
4898 | + return ERROR; |
4899 | + } |
4900 | + |
4901 | + /* allow users to specify directories to recurse into for config files */ |
4902 | + else if(!strcmp(varname,"include_dir")){ |
4903 | + |
4904 | + strncpy(config_file,varvalue,sizeof(config_file)-1); |
4905 | + config_file[sizeof(config_file)-1]='\x0'; |
4906 | + |
4907 | + /* strip trailing / if necessary */ |
4908 | + if(config_file[strlen(config_file)-1]=='/') |
4909 | + config_file[strlen(config_file)-1]='\x0'; |
4910 | + |
4911 | + /* process the config directory... */ |
4912 | + if(read_config_dir(config_file)==ERROR) |
4913 | + syslog(LOG_ERR,"Continuing with errors..."); |
4914 | + } |
4915 | + |
4916 | + /* allow users to specify individual config files to include */ |
4917 | + else if(!strcmp(varname,"include") || !strcmp(varname,"include_file")){ |
4918 | + |
4919 | + /* process the config file... */ |
4920 | + if(read_config_file(varvalue)==ERROR) |
4921 | + syslog(LOG_ERR,"Continuing with errors..."); |
4922 | + } |
4923 | + |
4924 | + else if(!strcmp(varname,"server_port")){ |
4925 | + server_port=atoi(varvalue); |
4926 | + if(server_port<1024){ |
4927 | + syslog(LOG_ERR,"Invalid port number specified in config file '%s' - Line %d\n",filename,line); |
4928 | + return ERROR; |
4929 | + } |
4930 | + } |
4931 | + else if(!strcmp(varname,"command_prefix")) |
4932 | + command_prefix=strdup(varvalue); |
4933 | + |
4934 | + else if(!strcmp(varname,"server_address")){ |
4935 | + strncpy(server_address,varvalue,sizeof(server_address) - 1); |
4936 | + server_address[sizeof(server_address)-1]='\0'; |
4937 | + } |
4938 | + else if(!strcmp(varname,"allowed_hosts")) { |
4939 | + allowed_hosts=strdup(varvalue); |
4940 | + parse_allowed_hosts(allowed_hosts); |
4941 | + } |
4942 | + else if(strstr(input_line,"command[")){ |
4943 | + temp_buffer=strtok(varname,"["); |
4944 | + temp_buffer=strtok(NULL,"]"); |
4945 | + if(temp_buffer==NULL){ |
4946 | + syslog(LOG_ERR,"Invalid command specified in config file '%s' - Line %d\n",filename,line); |
4947 | + return ERROR; |
4948 | + } |
4949 | + add_command(temp_buffer,varvalue); |
4950 | + } |
4951 | + |
4952 | + else if(strstr(input_buffer,"debug")){ |
4953 | + debug=atoi(varvalue); |
4954 | + if(debug>0) |
4955 | + debug=TRUE; |
4956 | + else |
4957 | + debug=FALSE; |
4958 | + } |
4959 | + |
4960 | + else if(!strcmp(varname,"nrpe_user")) |
4961 | + nrpe_user=strdup(varvalue); |
4962 | + |
4963 | + else if(!strcmp(varname,"nrpe_group")) |
4964 | + nrpe_group=strdup(varvalue); |
4965 | + |
4966 | + else if(!strcmp(varname,"dont_blame_nrpe")) |
4967 | + allow_arguments=(atoi(varvalue)==1)?TRUE:FALSE; |
4968 | + |
4969 | + else if(!strcmp(varname,"command_timeout")){ |
4970 | + command_timeout=atoi(varvalue); |
4971 | + if(command_timeout<1){ |
4972 | + syslog(LOG_ERR,"Invalid command_timeout specified in config file '%s' - Line %d\n",filename,line); |
4973 | + return ERROR; |
4974 | + } |
4975 | + } |
4976 | + |
4977 | + else if(!strcmp(varname,"connection_timeout")){ |
4978 | + connection_timeout=atoi(varvalue); |
4979 | + if(connection_timeout<1){ |
4980 | + syslog(LOG_ERR,"Invalid connection_timeout specified in config file '%s' - Line %d\n",filename,line); |
4981 | + return ERROR; |
4982 | + } |
4983 | + } |
4984 | + |
4985 | + else if(!strcmp(varname,"allow_weak_random_seed")) |
4986 | + allow_weak_random_seed=(atoi(varvalue)==1)?TRUE:FALSE; |
4987 | + |
4988 | + else if(!strcmp(varname,"pid_file")) |
4989 | + pid_file=strdup(varvalue); |
4990 | + |
4991 | + else if(!strcmp(varname,"log_facility")){ |
4992 | + if((get_log_facility(varvalue))==OK){ |
4993 | + /* re-open log using new facility */ |
4994 | + closelog(); |
4995 | + openlog("nrpe",LOG_PID,log_facility); |
4996 | + } |
4997 | + else |
4998 | + syslog(LOG_WARNING,"Invalid log_facility specified in config file '%s' - Line %d\n",filename,line); |
4999 | + } |
5000 | + |
The diff has been truncated for viewing.
Thanks. Uploaded.