summaryrefslogtreecommitdiffstats
path: root/web/attachments/301093-check_by_ssh_patch.diff
blob: ca57d51c8054a99d3cc236fc6cc77a4a77e44df9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
--- plugins/check_by_ssh.c
+++ plugins/check_by_ssh.c
@@ -38,8 +38,11 @@ const char *email = "nagiosplug-devel@li
 #include "netutils.h"
 #include "utils.h"
 #include "runcmd.h"
+#ifndef MAXARGS
+#define MAXARGS 255
+#endif
 
-int process_arguments (int, char **);
+int process_arguments (int, char **, char **);
 int validate_arguments (void);
 void print_help (void);
 void print_usage (void);
@@ -49,7 +52,6 @@ unsigned int services = 0;
 int skip_stdout = 0;
 int skip_stderr = 0;
 char *remotecmd = NULL;
-char *comm = NULL;
 char *hostname = NULL;
 char *outputfile = NULL;
 char *host_shortname = NULL;
@@ -68,9 +70,16 @@ main (int argc, char **argv)
 	time_t local_time;
 	FILE *fp = NULL;
 	struct output chld_out, chld_err;
+	char **newargv;
+
+
+	if ((newargv = calloc ((MAXARGS + 1), sizeof(char *))) == NULL)
+		printf (_("malloc failed"));
+
+	newargv[MAXARGS] = (char *)1;
 
 	remotecmd = "";
-	comm = strdup (SSH_COMMAND);
+	newargv[0] = strdup (SSH_COMMAND);
 
 	setlocale (LC_ALL, "");
 	bindtextdomain (PACKAGE, LOCALEDIR);
@@ -80,7 +89,7 @@ main (int argc, char **argv)
 	argv=np_extra_opts (&argc, argv, progname);
 
 	/* process arguments */
-	if (process_arguments (argc, argv) == ERROR)
+	if (process_arguments (argc, argv, newargv) == ERROR)
 		usage_va(_("Could not parse arguments"));
 
 	/* Set signal handling and alarm timeout */
@@ -90,11 +99,28 @@ main (int argc, char **argv)
 	alarm (timeout_interval);
 
 	/* run the command */
-	if (verbose)
-		printf ("%s\n", comm);
+	if (verbose) {
+		printf ("%s ", newargv[0]);
+		for (i=1; i <= MAXARGS; i++) {
+			if (newargv[i] > (char *)1 ) {
+					printf ("'%s' ", newargv[i]);
+			}
+		}
+		printf ("\n");
+	}
+
+	result = np_runcmdv(newargv[0], newargv, &chld_out, &chld_err, 0);
 
-	result = np_runcmd(comm, &chld_out, &chld_err, 0);
 
+	// free memory to prevent valgrind errors
+	for (i=0; i <= MAXARGS; i++) {
+		if (newargv[i] > (char *)1 ) {
+			free (newargv[i]);
+			newargv[i]=0;
+		}
+	}
+	free (newargv);
+	
 	if (skip_stdout == -1) /* --skip-stdout specified without argument */
 		skip_stdout = chld_out.lines;
 	if (skip_stderr == -1) /* --skip-stderr specified without argument */
@@ -152,10 +178,11 @@ main (int argc, char **argv)
 
 /* process command-line arguments */
 int
-process_arguments (int argc, char **argv)
+process_arguments (int argc, char **argv, char **newargv)
 {
 	int c;
 	char *p1, *p2;
+	char **opts = newargv + 2;
 
 	int option = 0;
 	static struct option longopts[] = {
@@ -222,7 +249,8 @@ process_arguments (int argc, char **argv
 		case 'p': /* port number */
 			if (!is_integer (optarg))
 				usage_va(_("Port must be a positive integer"));
-			asprintf (&comm,"%s -p %s", comm, optarg);
+			add_argument (&opts, "-p");
+			add_argument (&opts, optarg);
 			break;
 		case 'O':									/* output file */
 			outputfile = optarg;
@@ -246,16 +274,27 @@ process_arguments (int argc, char **argv
 		case 'u':
 			c = 'l';
 		case 'l':									/* login name */
+			add_argument (&opts, "-l");
+			add_argument (&opts, optarg);
+			break;
 		case 'i':									/* identity */
-			asprintf (&comm, "%s -%c %s", comm, c, optarg);
+			add_argument (&opts, "-i");
+			add_argument (&opts, optarg);
 			break;
-
 		case '1':									/* Pass these switches directly to ssh */
+			add_argument (&opts, "-1");
+			break;
 		case '2':									/* 1 to force version 1, 2 to force version 2 */
+			add_argument (&opts, "-2");
+			break;
 		case '4':									/* -4 for IPv4 */
-		case '6': 								/* -6 for IPv6 */
+			add_argument (&opts, "-4");
+			break;
+		case '6': 									/* -6 for IPv6 */
+			add_argument (&opts, "-6");
+			break;
 		case 'f':									/* fork to background */
-			asprintf (&comm, "%s -%c", comm, c);
+			add_argument (&opts, "-f");
 			break;
 		case 'C':									/* Command for remote machine */
 			commands++;
@@ -280,10 +319,11 @@ process_arguments (int argc, char **argv
 				skip_stderr = atoi (optarg);
 			break;
 		case 'o':									/* Extra options for the ssh command */
-			asprintf (&comm, "%s -%c '%s'", comm, c, optarg);
+			add_argument (&opts, "-o");
+			add_argument (&opts, optarg);
 			break;
 		case 'q':									/* Tell the ssh command to be quiet */
-			asprintf (&comm, "%s -%c", comm, c);
+			add_argument (&opts, "-q");
 			break;
 		default:									/* help */
 			usage5();
@@ -313,12 +353,25 @@ process_arguments (int argc, char **argv
 	if (remotecmd == NULL || strlen (remotecmd) <= 1)
 		usage_va(_("No remotecmd"));
 
-	asprintf (&comm, "%s %s '%s'", comm, hostname, remotecmd);
+	add_argument (&opts, remotecmd);
+	opts = newargv+1;
+	add_argument (&opts, hostname);
 
 	return validate_arguments ();
 }
 
+int add_argument (char ***argv, const char *str)
+{
+	
+	if (**argv == (char *)1)
+		die (STATE_UNKNOWN, _("%s: Argument limit of %d exceeded\n"), progname, MAXARGS);
 
+	**argv = (char *)malloc((strlen(str) * sizeof(char)) +1);
+
+	strcpy(**argv, str);
+	(*argv)++;
+	return 0;
+}
 
 int
 validate_arguments (void)
--- plugins/runcmd.c
+++ plugins/runcmd.c
@@ -46,6 +46,7 @@
 #ifdef HAVE_SYS_WAIT_H
 # include <sys/wait.h>
 #endif
+#include <sys/ioctl.h>
 
 /** macros **/
 #ifndef WEXITSTATUS
@@ -87,6 +88,8 @@ static long maxfd = 0;
 static int np_runcmd_open(const char *, int *, int *)
 	__attribute__((__nonnull__(1, 2, 3)));
 
+static int np_runcmd_open_argv(const char *, char **, int *, int *);
+
 static int np_fetch_output(int, output *, int)
 	__attribute__((__nonnull__(2)));
 
@@ -118,24 +121,14 @@ void np_runcmd_init(void)
 static int
 np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
 {
-	char *env[2];
 	char *cmd = NULL;
 	char **argv = NULL;
 	char *str;
 	int argc;
 	size_t cmdlen;
-	pid_t pid;
-#ifdef RLIMIT_CORE
-	struct rlimit limit;
-#endif
 
 	int i = 0;
 
-	if(!np_pids) NP_RUNCMD_INIT;
-
-	env[0] = strdup("LC_ALL=C");
-	env[1] = '\0';
-
 	/* if no command was passed, return with no error */
 	if (cmdstring == NULL)
 		return -1;
@@ -191,6 +184,35 @@ np_runcmd_open(const char *cmdstring, in
 		argv[i++] = str;
 	}
 
+
+	return (np_runcmd_open_argv(argv[0], argv, pfd, pfderr));
+}
+
+static int
+np_runcmd_open_argv(const char *cmdstring, char **argv, int *pfd, int *pfderr)
+{
+	char *env[2];
+	pid_t pid;
+#ifdef RLIMIT_CORE
+	struct rlimit limit;
+#endif
+
+	int i = 0;
+	int master,slave;
+
+	if(!np_pids) NP_RUNCMD_INIT;
+
+	env[0] = strdup("LC_ALL=C");
+	env[1] = '\0';
+
+	/* if no command was passed, return with an error */
+	if (cmdstring == NULL)
+		return -1;
+
+	/* make sure that the command name is also argv[0] */
+	if (strcmp(cmdstring, argv[0]) != 0)
+		return -1;
+
 	if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0)
 		return -1; /* errno set by the failing function */
 
@@ -202,6 +224,11 @@ np_runcmd_open(const char *cmdstring, in
 		limit.rlim_cur = 0;
 		setrlimit (RLIMIT_CORE, &limit);
 #endif
+#ifdef TIOCNOTTY
+		/* disassociate from tty to prevent e.g. ssh asking for passwords */
+		if(isatty(STDOUT_FILENO))
+			ioctl(STDOUT_FILENO, TIOCNOTTY);
+#endif
 		close (pfd[0]);
 		if (pfd[1] != STDOUT_FILENO) {
 			dup2 (pfd[1], STDOUT_FILENO);
@@ -235,7 +262,6 @@ np_runcmd_open(const char *cmdstring, in
 	return pfd[0];
 }
 
-
 static int
 np_runcmd_close(int fd)
 {
@@ -360,3 +386,21 @@ np_runcmd(const char *cmd, output *out, 
 
 	return np_runcmd_close(fd);
 }
+
+int
+np_runcmdv(const char *cmd, char ** argv, output *out, output *err, int flags)
+{
+	int fd, pfd_out[2], pfd_err[2];
+
+	/* initialize the structs */
+	if(out) memset(out, 0, sizeof(output));
+	if(err) memset(err, 0, sizeof(output));
+
+	if((fd = np_runcmd_open_argv(cmd, argv, pfd_out, pfd_err)) == -1)
+		die (STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd);
+
+	if(out) out->lines = np_fetch_output(pfd_out[0], out, flags);
+	if(err) err->lines = np_fetch_output(pfd_err[0], err, flags);
+
+	return np_runcmd_close(fd);
+}
--- plugins/runcmd.h
+++ plugins/runcmd.h
@@ -40,6 +40,7 @@ typedef struct output output;
 
 /** prototypes **/
 int np_runcmd(const char *, output *, output *, int);
+int np_runcmdv(const char *, char **, output *, output *, int);
 void popen_timeout_alarm_handler(int)
 	__attribute__((__noreturn__));