Code

Remove getopt_long checks
[nagiosplug.git] / plugins / check_radius.c
1 /******************************************************************************
2  *
3  * Program: radius server check plugin for Nagios
4  * License: GPL
5  *
6  * License Information:
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  *
24  *****************************************************************************/
26 const char *progname = "check_radius";
27 #define REVISION "$Revision$"
28 #define COPYRIGHT "1999-2001"
29 #define AUTHORS "Robert August Vincent II/Karl DeBisschop"
30 #define EMAIL "kdebisschop@users.sourceforge.net"
31 #define SUMMARY "Tests to see if a radius server is accepting connections.\n"
33 #define OPTIONS "\
34 -H host -F config_file -u username -p password\'\
35               [-P port] [-t timeout] [-r retries] [-e expect]"
37 #define LONGOPTIONS "\
38  -H, --hostname=HOST\n\
39     Host name argument for servers using host headers (use numeric\n\
40     address if possible to bypass DNS lookup).\n\
41  -P, --port=INTEGER\n\
42     Port number (default: %d)\n\
43  -u, --username=STRING\n\
44     The user to authenticate\n\
45  -p, --password=STRING\n\
46     Password for autentication (SECURITY RISK)\n\
47  -F, --filename=STRING\n\
48     Configuration file\n\
49  -e, --expect=STRING\n\
50     Response string to expect from the server\n\
51  -r, --retries=INTEGER\n\
52     Number of times to retry a failed connection\n\
53  -t, --timeout=INTEGER\n\
54     Seconds before connection times out (default: %d)\n\
55  -v, --verbose\n\
56     Show details for command-line debugging (do not use with nagios server)\n\
57  -h, --help\n\
58     Print detailed help screen\n\
59  -V, --version\n\
60     Print version information\n"
62 #define DESCRIPTION "\
63 This plugin tests a radius server to see if it is accepting connections.\n\
64 \n\
65 The server to test must be specified in the invocation, as well as a user\n\
66 name and password. A configuration file may also be present. The format of\n\
67 the configuration file is described in the radiusclient library sources.\n\
68 \n\
69 The password option presents a substantial security issue because the\n\
70 password can be determined by careful watching of the command line in\n\
71 a process listing.  This risk is exacerbated because nagios will\n\
72 run the plugin at regular prdictable intervals.  Please be sure that\n\
73 the password used does not allow access to sensitive system resources,\n\
74 otherwise compormise could occur.\n"
76 #include "config.h"
77 #include "common.h"
78 #include "utils.h"
79 #include <radiusclient.h>
81 int process_arguments (int, char **);
82 void print_usage (void);
83 void print_help (void);
85 char *server = NULL;
86 int port = PW_AUTH_UDP_PORT;
87 char *username = NULL;
88 char *password = NULL;
89 char *expect = NULL;
90 char *config_file = NULL;
91 int retries = 1;
92 int verbose = FALSE;
94 ENV *env = NULL;
96 /******************************************************************************
98 The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
99 tags in the comments. With in the tags, the XML is assembled sequentially.
100 You can define entities in tags. You also have all the #defines available as
101 entities.
103 Please note that all tags must be lowercase to use the DocBook XML DTD.
105 @@-<article>
107 <sect1>
108 <title>Quick Reference</title>
109 <!-- The refentry forms a manpage -->
110 <refentry>
111 <refmeta>
112 <manvolnum>5<manvolnum>
113 </refmeta>
114 <refnamdiv>
115 <refname>&progname;</refname>
116 <refpurpose>&SUMMARY;</refpurpose>
117 </refnamdiv>
118 </refentry>
119 </sect1>
121 <sect1>
122 <title>FAQ</title>
123 </sect1>
125 <sect1>
126 <title>Theory, Installation, and Operation</title>
128 <sect2>
129 <title>General Description</title>
130 <para>
131 &DESCRIPTION;
132 </para>
133 </sect2>
135 <sect2>
136 <title>Future Enhancements</title>
137 <para>Todo List</para>
138 <itemizedlist>
139 <listitem>Add option to get password from a secured file rather than the command line</listitem>
140 </itemizedlist>
141 </sect2>
144 <sect2>
145 <title>Functions</title>
146 -@@
147 ******************************************************************************/
149 int
150 main (int argc, char **argv)
152         UINT4 service;
153         char msg[BUFFER_LEN];
154         SEND_DATA data = { 0 };
155         int result;
156         UINT4 client_id;
158         if (process_arguments (argc, argv) == ERROR)
159                 usage ("Could not parse arguments\n");
161         if ((config_file && rc_read_config (config_file)) ||
162                         rc_read_dictionary (rc_conf_str ("dictionary")))
163                 terminate (STATE_UNKNOWN, "Config file error");
165         service = PW_AUTHENTICATE_ONLY;
167         if (!(rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
168                                 rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) &&
169                                 rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0)))
170                 terminate (STATE_UNKNOWN, "Out of Memory?");
172         /* 
173          * Fill in NAS-IP-Address 
174          */
176         if ((client_id = rc_own_ipaddress ()) == 0)
177                 return (ERROR_RC);
179         if (rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) ==
180                         NULL) return (ERROR_RC);
182         rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, timeout_interval,
183                                                          retries);
185         result = rc_send_server (&data, msg);
186         rc_avpair_free (data.send_pairs);
187         if (data.receive_pairs)
188                 rc_avpair_free (data.receive_pairs);
190         if (result == TIMEOUT_RC)
191                 terminate (STATE_CRITICAL, "Timeout");
192         if (result == ERROR_RC)
193                 terminate (STATE_CRITICAL, "Auth Error");
194         if (result == BADRESP_RC)
195                 terminate (STATE_WARNING, "Auth Failed");
196         if (expect && !strstr (msg, expect))
197                 terminate (STATE_WARNING, msg);
198         if (result == OK_RC)
199                 terminate (STATE_OK, "Auth OK");
200         return (0);
205 /* process command-line arguments */
206 int
207 process_arguments (int argc, char **argv)
209         int c;
211         int option_index = 0;
212         static struct option long_options[] = {
213                 {"hostname", required_argument, 0, 'H'},
214                 {"port", required_argument, 0, 'P'},
215                 {"username", required_argument, 0, 'u'},
216                 {"password", required_argument, 0, 'p'},
217                 {"filename", required_argument, 0, 'F'},
218                 {"expect", required_argument, 0, 'e'},
219                 {"retries", required_argument, 0, 'r'},
220                 {"timeout", required_argument, 0, 't'},
221                 {"verbose", no_argument, 0, 'v'},
222                 {"version", no_argument, 0, 'V'},
223                 {"help", no_argument, 0, 'h'},
224                 {0, 0, 0, 0}
225         };
227         if (argc < 2)
228                 return ERROR;
230         if (argc == 9) {
231                 config_file = argv[1];
232                 username = argv[2];
233                 password = argv[3];
234                 if (is_intpos (argv[4]))
235                         timeout_interval = atoi (argv[4]);
236                 else
237                         usage ("Timeout interval must be a positive integer");
238                 if (is_intpos (argv[5]))
239                         retries = atoi (argv[5]);
240                 else
241                         usage ("Number of retries must be a positive integer");
242                 server = argv[6];
243                 if (is_intpos (argv[7]))
244                         port = atoi (argv[7]);
245                 else
246                         usage ("Server port must be a positive integer");
247                 expect = argv[8];
248                 return OK;
249         }
251         while (1) {
252                 c = getopt_long (argc, argv, "+hVvH:P:F:u:p:t:r:e:", long_options,
253                                                                          &option_index);
255                 if (c == -1 || c == EOF || c == 1)
256                         break;
258                 switch (c) {
259                 case '?':                                                                       /* print short usage statement if args not parsable */
260                         printf ("%s: Unknown argument: %s\n\n", progname, optarg);
261                         print_usage ();
262                         exit (STATE_UNKNOWN);
263                 case 'h':                                                                       /* help */
264                         print_help ();
265                         exit (OK);
266                 case 'V':                                                                       /* version */
267                         print_revision (progname, "$Revision$");
268                         exit (OK);
269                 case 'v':                                                                       /* verbose mode */
270                         verbose = TRUE;
271                         break;
272                 case 'H':                                                                       /* hostname */
273                         if (is_host (optarg) == FALSE) {
274                                 printf ("Invalid host name/address\n\n");
275                                 print_usage ();
276                                 exit (STATE_UNKNOWN);
277                         }
278                         server = optarg;
279                         break;
280                 case 'P':                                                                       /* port */
281                         if (is_intnonneg (optarg))
282                                 port = atoi (optarg);
283                         else
284                                 usage ("Server port must be a positive integer");
285                         break;
286                 case 'u':                                                                       /* username */
287                         username = optarg;
288                         break;
289                 case 'p':                                                                       /* password */
290                         password = optarg;
291                         break;
292                 case 'F':                                                                       /* configuration file */
293                         config_file = optarg;
294                         break;
295                 case 'e':                                                                       /* expect */
296                         expect = optarg;
297                         break;
298                 case 'r':                                                                       /* retries */
299                         if (is_intpos (optarg))
300                                 retries = atoi (optarg);
301                         else
302                                 usage ("Number of retries must be a positive integer");
303                         break;
304                 case 't':                                                                       /* timeout */
305                         if (is_intpos (optarg))
306                                 timeout_interval = atoi (optarg);
307                         else
308                                 usage ("Timeout interval must be a positive integer");
309                         break;
310                 }
311         }
312         return OK;
314 \f
317 void
318 print_help (void)
320         print_revision (progname, REVISION);
321         printf
322                 ("Copyright (c) %s %s <%s>\n\n%s\n",
323                  COPYRIGHT, AUTHORS, EMAIL, SUMMARY);
324         print_usage ();
325         printf
326                 ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n", 
327                  port, timeout_interval);
328         support ();
332 void
333 print_usage (void)
335         printf ("Usage:\n" " %s %s\n"
336                                         " %s (-h | --help) for detailed help\n"
337                                         " %s (-V | --version) for version information\n",
338                                         progname, OPTIONS, progname, progname);