summaryrefslogtreecommitdiffstats
path: root/plugins/check_by_ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_by_ssh.c')
-rw-r--r--plugins/check_by_ssh.c150
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
31int process_arguments (int, char **); 31int process_arguments (int, char **);
32int validate_arguments (void); 32int validate_arguments (void);
@@ -35,7 +35,7 @@ void print_usage (void);
35 35
36int commands = 0; 36int commands = 0;
37int services = 0; 37int services = 0;
38int skip_lines = 0; 38int skip = 0;
39char *remotecmd = NULL; 39char *remotecmd = NULL;
40char *comm = NULL; 40char *comm = NULL;
41char *hostname = NULL; 41char *hostname = NULL;
@@ -49,19 +49,16 @@ int
49main (int argc, char **argv) 49main (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