diff options
Diffstat (limited to 'plugins/check_by_ssh.c')
-rw-r--r-- | plugins/check_by_ssh.c | 150 |
1 files changed, 55 insertions, 95 deletions
diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c index 2ceee28f..b777b072 100644 --- a/plugins/check_by_ssh.c +++ b/plugins/check_by_ssh.c | |||
@@ -26,7 +26,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
26 | #include "common.h" | 26 | #include "common.h" |
27 | #include "netutils.h" | 27 | #include "netutils.h" |
28 | #include "utils.h" | 28 | #include "utils.h" |
29 | #include "popen.h" | 29 | #include "runcmd.h" |
30 | 30 | ||
31 | int process_arguments (int, char **); | 31 | int process_arguments (int, char **); |
32 | int validate_arguments (void); | 32 | int validate_arguments (void); |
@@ -35,7 +35,7 @@ void print_usage (void); | |||
35 | 35 | ||
36 | int commands = 0; | 36 | int commands = 0; |
37 | int services = 0; | 37 | int services = 0; |
38 | int skip_lines = 0; | 38 | int skip = 0; |
39 | char *remotecmd = NULL; | 39 | char *remotecmd = NULL; |
40 | char *comm = NULL; | 40 | char *comm = NULL; |
41 | char *hostname = NULL; | 41 | char *hostname = NULL; |
@@ -49,19 +49,16 @@ int | |||
49 | main (int argc, char **argv) | 49 | main (int argc, char **argv) |
50 | { | 50 | { |
51 | 51 | ||
52 | char input_buffer[MAX_INPUT_BUFFER]; | ||
53 | char *result_text; | ||
54 | char *status_text; | 52 | char *status_text; |
55 | char *output; | ||
56 | char *eol = NULL; | ||
57 | int cresult; | 53 | int cresult; |
58 | int result = STATE_UNKNOWN; | 54 | int result = STATE_UNKNOWN; |
55 | int i; | ||
59 | time_t local_time; | 56 | time_t local_time; |
60 | FILE *fp = NULL; | 57 | FILE *fp = NULL; |
58 | struct output chld_out, chld_err; | ||
61 | 59 | ||
62 | remotecmd = strdup (""); | 60 | remotecmd = ""; |
63 | comm = strdup (SSH_COMMAND); | 61 | comm = strdup (SSH_COMMAND); |
64 | result_text = strdup (""); | ||
65 | 62 | ||
66 | setlocale (LC_ALL, ""); | 63 | setlocale (LC_ALL, ""); |
67 | bindtextdomain (PACKAGE, LOCALEDIR); | 64 | bindtextdomain (PACKAGE, LOCALEDIR); |
@@ -69,100 +66,62 @@ main (int argc, char **argv) | |||
69 | 66 | ||
70 | /* process arguments */ | 67 | /* process arguments */ |
71 | if (process_arguments (argc, argv) == ERROR) | 68 | if (process_arguments (argc, argv) == ERROR) |
72 | usage4 (_("Could not parse arguments")); | 69 | usage_va(_("Could not parse arguments")); |
73 | 70 | ||
74 | /* Set signal handling and alarm timeout */ | 71 | /* Set signal handling and alarm timeout */ |
75 | if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { | 72 | if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { |
76 | usage4 (_("Cannot catch SIGALRM")); | 73 | usage_va(_("Cannot catch SIGALRM")); |
77 | } | 74 | } |
78 | alarm (timeout_interval); | 75 | alarm (timeout_interval); |
79 | 76 | ||
80 | /* run the command */ | 77 | /* run the command */ |
81 | |||
82 | if (verbose) | 78 | if (verbose) |
83 | printf ("%s\n", comm); | 79 | printf ("%s\n", comm); |
84 | 80 | ||
85 | child_process = spopen (comm); | 81 | result = np_runcmd(comm, &chld_out, &chld_err, 0); |
86 | 82 | /* UNKNOWN if output found on stderr */ | |
87 | if (child_process == NULL) { | 83 | if(chld_err.buflen) { |
88 | printf (_("Could not open pipe: %s\n"), comm); | 84 | printf(_("Remote command execution failed: %s\n"), |
85 | chld_err.buflen ? chld_err.buf : _("Unknown error")); | ||
89 | return STATE_UNKNOWN; | 86 | return STATE_UNKNOWN; |
90 | } | 87 | } |
91 | 88 | ||
92 | 89 | /* this is simple if we're not supposed to be passive. | |
93 | /* open STDERR for spopen */ | 90 | * Wrap up quickly and keep the tricks below */ |
94 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | 91 | if(!passive) { |
95 | if (child_stderr == NULL) { | 92 | printf ("%s\n", skip < chld_out.lines ? chld_out.line[skip] : chld_out.buf); |
96 | printf (_("Could not open stderr for %s\n"), SSH_COMMAND); | 93 | return result; /* return error status from remote command */ |
97 | } | 94 | } |
98 | 95 | ||
99 | 96 | ||
100 | /* build up results from remote command in result_text */ | 97 | /* |
101 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) | 98 | * Passive mode |
102 | asprintf (&result_text, "%s%s", result_text, input_buffer); | 99 | */ |
103 | |||
104 | /* WARNING if output found on stderr */ | ||
105 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { | ||
106 | if (skip_lines > 0) { | ||
107 | if (input_buffer[strlen(input_buffer)-1] == '\n') { | ||
108 | skip_lines--; | ||
109 | } | ||
110 | } else { | ||
111 | printf ("%s", input_buffer); | ||
112 | result = STATE_WARNING; | ||
113 | } | ||
114 | } | ||
115 | (void) fclose (child_stderr); | ||
116 | if (result == STATE_WARNING) | ||
117 | return result; | ||
118 | |||
119 | |||
120 | /* close the pipe */ | ||
121 | result = spclose (child_process); | ||
122 | |||
123 | 100 | ||
124 | /* process output */ | 101 | /* process output */ |
125 | if (passive) { | 102 | if (!(fp = fopen (outputfile, "a"))) { |
103 | printf (_("SSH WARNING: could not open %s\n"), outputfile); | ||
104 | exit (STATE_UNKNOWN); | ||
105 | } | ||
126 | 106 | ||
127 | if (!(fp = fopen (outputfile, "a"))) { | 107 | local_time = time (NULL); |
128 | printf (_("SSH WARNING: could not open %s\n"), outputfile); | 108 | commands = 0; |
129 | exit (STATE_UNKNOWN); | 109 | for(i = skip; chld_out.line[i]; i++) { |
110 | status_text = strstr (chld_out.line[i], "STATUS CODE: "); | ||
111 | if (status_text == NULL) { | ||
112 | printf ("%s", chld_out.line[i]); | ||
113 | return result; | ||
130 | } | 114 | } |
131 | 115 | if (service[commands] && status_text | |
132 | local_time = time (NULL); | 116 | && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) |
133 | commands = 0; | 117 | { |
134 | while (result_text && strlen(result_text) > 0) { | 118 | fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", |
135 | status_text = strstr (result_text, "STATUS CODE: "); | 119 | (int) local_time, host_shortname, service[commands++], |
136 | if (status_text == NULL) { | 120 | cresult, chld_out.line[i]); |
137 | printf ("%s", result_text); | ||
138 | return result; | ||
139 | } | ||
140 | asprintf (&output, "%s", result_text); | ||
141 | result_text = strnl (status_text); | ||
142 | eol = strpbrk (output, "\r\n"); | ||
143 | if (eol != NULL) | ||
144 | eol[0] = 0; | ||
145 | if (service[commands] && status_text | ||
146 | && sscanf (status_text, "STATUS CODE: %d", &cresult) == 1) { | ||
147 | fprintf (fp, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", | ||
148 | (int) local_time, host_shortname, service[commands++], cresult, | ||
149 | output); | ||
150 | } | ||
151 | } | 121 | } |
152 | |||
153 | } | ||
154 | |||
155 | |||
156 | /* print the first line from the remote command */ | ||
157 | else { | ||
158 | eol = strpbrk (result_text, "\r\n"); | ||
159 | if (eol) | ||
160 | eol[0] = 0; | ||
161 | printf ("%s\n", result_text); | ||
162 | } | 122 | } |
163 | 123 | ||
164 | 124 | /* force an OK state */ | |
165 | /* return error status from remote command */ | ||
166 | return result; | 125 | return result; |
167 | } | 126 | } |
168 | 127 | ||
@@ -206,14 +165,12 @@ process_arguments (int argc, char **argv) | |||
206 | 165 | ||
207 | while (1) { | 166 | while (1) { |
208 | c = getopt_long (argc, argv, "Vvh1246ft:H:O:p:i:u:l:C:S:n:s:", longopts, | 167 | c = getopt_long (argc, argv, "Vvh1246ft:H:O:p:i:u:l:C:S:n:s:", longopts, |
209 | &option); | 168 | &option); |
210 | 169 | ||
211 | if (c == -1 || c == EOF) | 170 | if (c == -1 || c == EOF) |
212 | break; | 171 | break; |
213 | 172 | ||
214 | switch (c) { | 173 | switch (c) { |
215 | case '?': /* help */ | ||
216 | usage2 (_("Unknown argument"), optarg); | ||
217 | case 'V': /* version */ | 174 | case 'V': /* version */ |
218 | print_revision (progname, revision); | 175 | print_revision (progname, revision); |
219 | exit (STATE_OK); | 176 | exit (STATE_OK); |
@@ -225,18 +182,17 @@ process_arguments (int argc, char **argv) | |||
225 | break; | 182 | break; |
226 | case 't': /* timeout period */ | 183 | case 't': /* timeout period */ |
227 | if (!is_integer (optarg)) | 184 | if (!is_integer (optarg)) |
228 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 185 | usage_va(_("Timeout interval must be a positive integer")); |
229 | else | 186 | else |
230 | timeout_interval = atoi (optarg); | 187 | timeout_interval = atoi (optarg); |
231 | break; | 188 | break; |
232 | case 'H': /* host */ | 189 | case 'H': /* host */ |
233 | if (!is_host (optarg)) | 190 | host_or_die(optarg); |
234 | usage2 (_("Invalid hostname/address"), optarg); | ||
235 | hostname = optarg; | 191 | hostname = optarg; |
236 | break; | 192 | break; |
237 | case 'p': /* port number */ | 193 | case 'p': /* port number */ |
238 | if (!is_integer (optarg)) | 194 | if (!is_integer (optarg)) |
239 | usage2 (_("Port must be a positive integer"), optarg); | 195 | usage_va(_("Port must be a positive integer")); |
240 | asprintf (&comm,"%s -p %s", comm, optarg); | 196 | asprintf (&comm,"%s -p %s", comm, optarg); |
241 | break; | 197 | break; |
242 | case 'O': /* output file */ | 198 | case 'O': /* output file */ |
@@ -244,25 +200,27 @@ process_arguments (int argc, char **argv) | |||
244 | passive = TRUE; | 200 | passive = TRUE; |
245 | break; | 201 | break; |
246 | case 's': /* description of service to check */ | 202 | case 's': /* description of service to check */ |
247 | service = realloc (service, (++services) * sizeof(char *)); | ||
248 | p1 = optarg; | 203 | p1 = optarg; |
204 | service = realloc (service, (++services) * sizeof(char *)); | ||
249 | while ((p2 = index (p1, ':'))) { | 205 | while ((p2 = index (p1, ':'))) { |
250 | *p2 = '\0'; | 206 | *p2 = '\0'; |
251 | asprintf (&service[services-1], "%s", p1); | 207 | service[services - 1] = p1; |
252 | service = realloc (service, (++services) * sizeof(char *)); | 208 | service = realloc (service, (++services) * sizeof(char *)); |
253 | p1 = p2 + 1; | 209 | p1 = p2 + 1; |
254 | } | 210 | } |
255 | asprintf (&service[services-1], "%s", p1); | 211 | service[services - 1] = p1; |
256 | break; | 212 | break; |
257 | case 'n': /* short name of host in nagios configuration */ | 213 | case 'n': /* short name of host in nagios configuration */ |
258 | host_shortname = optarg; | 214 | host_shortname = optarg; |
259 | break; | 215 | break; |
216 | |||
260 | case 'u': | 217 | case 'u': |
261 | c = 'l'; | 218 | c = 'l'; |
262 | case 'l': /* login name */ | 219 | case 'l': /* login name */ |
263 | case 'i': /* identity */ | 220 | case 'i': /* identity */ |
264 | asprintf (&comm, "%s -%c %s", comm, c, optarg); | 221 | asprintf (&comm, "%s -%c %s", comm, c, optarg); |
265 | break; | 222 | break; |
223 | |||
266 | case '1': /* Pass these switches directly to ssh */ | 224 | case '1': /* Pass these switches directly to ssh */ |
267 | case '2': /* 1 to force version 1, 2 to force version 2 */ | 225 | case '2': /* 1 to force version 1, 2 to force version 2 */ |
268 | case '4': /* -4 for IPv4 */ | 226 | case '4': /* -4 for IPv4 */ |
@@ -278,10 +236,12 @@ process_arguments (int argc, char **argv) | |||
278 | break; | 236 | break; |
279 | case 'S': /* Skip n lines in the output to ignore system banner */ | 237 | case 'S': /* Skip n lines in the output to ignore system banner */ |
280 | if (!is_integer (optarg)) | 238 | if (!is_integer (optarg)) |
281 | usage2 (_("skip lines must be an integer"), optarg); | 239 | usage_va(_("skip lines must be an integer")); |
282 | else | 240 | else |
283 | skip_lines = atoi (optarg); | 241 | skip = atoi (optarg); |
284 | break; | 242 | break; |
243 | default: /* help */ | ||
244 | usage_va(_("Unknown argument - %s"), optarg); | ||
285 | } | 245 | } |
286 | } | 246 | } |
287 | 247 | ||
@@ -289,8 +249,8 @@ process_arguments (int argc, char **argv) | |||
289 | if (hostname == NULL) { | 249 | if (hostname == NULL) { |
290 | if (c <= argc) { | 250 | if (c <= argc) { |
291 | die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname); | 251 | die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname); |
292 | } else if (!is_host (argv[c])) | 252 | } |
293 | die (STATE_UNKNOWN, "%s: %s %s\n", progname, _("Invalid hostname/address"), argv[c]); | 253 | host_or_die(argv[c]); |
294 | hostname = argv[c++]; | 254 | hostname = argv[c++]; |
295 | } | 255 | } |
296 | 256 | ||
@@ -306,7 +266,7 @@ process_arguments (int argc, char **argv) | |||
306 | asprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd); | 266 | asprintf (&remotecmd, "%s;echo STATUS CODE: $?;", remotecmd); |
307 | 267 | ||
308 | if (remotecmd == NULL || strlen (remotecmd) <= 1) | 268 | if (remotecmd == NULL || strlen (remotecmd) <= 1) |
309 | usage4 (_("No remotecmd")); | 269 | usage_va(_("No remotecmd")); |
310 | 270 | ||
311 | asprintf (&comm, "%s %s '%s'", comm, hostname, remotecmd); | 271 | asprintf (&comm, "%s %s '%s'", comm, hostname, remotecmd); |
312 | 272 | ||