Code

Making messages more consistent
[nagiosplug.git] / plugins / check_radius.c
1 /******************************************************************************
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; either version 2 of the License, or
6  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  GNU General Public License for more details.
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  ******************************************************************************/
19 const char *progname = "check_radius";
20 const char *revision = "$Revision$";
21 const char *copyright = "2000-2003";
22 const char *email = "nagiosplug-devel@lists.sourceforge.net";
24 #include "common.h"
25 #include "utils.h"
26 #include "netutils.h"
27 #include <radiusclient.h>
29 int process_arguments (int, char **);
30 void print_help (void);
31 void print_usage (void);
33 char *server = NULL;
34 char *username = NULL;
35 char *password = NULL;
36 char *nasid = NULL;
37 char *expect = NULL;
38 char *config_file = NULL;
39 unsigned short port = PW_AUTH_UDP_PORT;
40 int retries = 1;
41 int verbose = FALSE;
42 ENV *env = NULL;
44 /******************************************************************************
46 The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
47 tags in the comments. With in the tags, the XML is assembled sequentially.
48 You can define entities in tags. You also have all the #defines available as
49 entities.
51 Please note that all tags must be lowercase to use the DocBook XML DTD.
53 @@-<article>
55 <sect1>
56 <title>Quick Reference</title>
57 <!-- The refentry forms a manpage -->
58 <refentry>
59 <refmeta>
60 <manvolnum>5<manvolnum>
61 </refmeta>
62 <refnamdiv>
63 <refname>&progname;</refname>
64 <refpurpose>&SUMMARY;</refpurpose>
65 </refnamdiv>
66 </refentry>
67 </sect1>
69 <sect1>
70 <title>FAQ</title>
71 </sect1>
73 <sect1>
74 <title>Theory, Installation, and Operation</title>
76 <sect2>
77 <title>General Description</title>
78 <para>
79 &DESCRIPTION;
80 </para>
81 </sect2>
83 <sect2>
84 <title>Future Enhancements</title>
85 <para>Todo List</para>
86 <itemizedlist>
87 <listitem>Add option to get password from a secured file rather than the command line</listitem>
88 </itemizedlist>
89 </sect2>
92 <sect2>
93 <title>Functions</title>
94 -@@
95 ******************************************************************************/
97 int
98 main (int argc, char **argv)
99 {
100         UINT4 service;
101         char msg[BUFFER_LEN];
102         SEND_DATA data;
103         int result;
104         UINT4 client_id;
105         char *str;
107         setlocale (LC_ALL, "");
108         bindtextdomain (PACKAGE, LOCALEDIR);
109         textdomain (PACKAGE);
111         if (process_arguments (argc, argv) == ERROR)
112                 usage (_("Could not parse arguments\n"));
114         str = strdup ("dictionary");
115         if ((config_file && rc_read_config (config_file)) ||
116                         rc_read_dictionary (rc_conf_str (str)))
117                 die (STATE_UNKNOWN, _("Config file error"));
119         service = PW_AUTHENTICATE_ONLY;
121         if (!(rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
122                                 rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) &&
123                                 rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0) &&
124                                 (nasid==NULL || rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))))
125                 die (STATE_UNKNOWN, _("Out of Memory?"));
127         /* 
128          * Fill in NAS-IP-Address 
129          */
131         if ((client_id = rc_own_ipaddress ()) == 0)
132                 return (ERROR_RC);
134         if (rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) ==
135                         NULL) return (ERROR_RC);
137         rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval,
138                      retries);
140         result = rc_send_server (&data, msg);
141         rc_avpair_free (data.send_pairs);
142         if (data.receive_pairs)
143                 rc_avpair_free (data.receive_pairs);
145         if (result == TIMEOUT_RC)
146                 die (STATE_CRITICAL, _("Timeout"));
147         if (result == ERROR_RC)
148                 die (STATE_CRITICAL, _("Auth Error"));
149         if (result == BADRESP_RC)
150                 die (STATE_WARNING, _("Auth Failed"));
151         if (expect && !strstr (msg, expect))
152                 die (STATE_WARNING, "%s", msg);
153         if (result == OK_RC)
154                 die (STATE_OK, _("Auth OK"));
155         return (0);
160 /* process command-line arguments */
161 int
162 process_arguments (int argc, char **argv)
164         int c;
166         int option = 0;
167         static struct option longopts[] = {
168                 {"hostname", required_argument, 0, 'H'},
169                 {"port", required_argument, 0, 'P'},
170                 {"username", required_argument, 0, 'u'},
171                 {"password", required_argument, 0, 'p'},
172                 {"nas-id", required_argument, 0, 'n'},
173                 {"filename", required_argument, 0, 'F'},
174                 {"expect", required_argument, 0, 'e'},
175                 {"retries", required_argument, 0, 'r'},
176                 {"timeout", required_argument, 0, 't'},
177                 {"verbose", no_argument, 0, 'v'},
178                 {"version", no_argument, 0, 'V'},
179                 {"help", no_argument, 0, 'h'},
180                 {0, 0, 0, 0}
181         };
183         if (argc < 2)
184                 return ERROR;
186         if (argc == 9) {
187                 config_file = argv[1];
188                 username = argv[2];
189                 password = argv[3];
190                 if (is_intpos (argv[4]))
191                         timeout_interval = atoi (argv[4]);
192                 else
193                         usage2 (_("Timeout interval must be a positive integer"), optarg);
194                 if (is_intpos (argv[5]))
195                         retries = atoi (argv[5]);
196                 else
197                         usage (_("Number of retries must be a positive integer"));
198                 server = argv[6];
199                 if (is_intpos (argv[7]))
200                         port = atoi (argv[7]);
201                 else
202                         usage (_("Server port must be a positive integer"));
203                 expect = argv[8];
204                 return OK;
205         }
207         while (1) {
208                 c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:t:r:e:", longopts,
209                                                                          &option);
211                 if (c == -1 || c == EOF || c == 1)
212                         break;
214                 switch (c) {
215                 case '?':                                                                       /* print short usage statement if args not parsable */
216                         printf (_("%s: Unknown argument: %s\n\n"), progname, optarg);
217                         print_usage ();
218                         exit (STATE_UNKNOWN);
219                 case 'h':                                                                       /* help */
220                         print_help ();
221                         exit (OK);
222                 case 'V':                                                                       /* version */
223                         print_revision (progname, revision);
224                         exit (OK);
225                 case 'v':                                                                       /* verbose mode */
226                         verbose = TRUE;
227                         break;
228                 case 'H':                                                                       /* hostname */
229                         if (is_host (optarg) == FALSE) {
230                                 usage2 (_("Invalid host name/address"), optarg);
231                         }
232                         server = optarg;
233                         break;
234                 case 'P':                                                                       /* port */
235                         if (is_intnonneg (optarg))
236                                 port = atoi (optarg);
237                         else
238                                 usage (_("Server port must be a positive integer"));
239                         break;
240                 case 'u':                                                                       /* username */
241                         username = optarg;
242                         break;
243                 case 'p':                                                                       /* password */
244                         password = optarg;
245                         break;
246                 case 'n':                                                                       /* nas id */
247                         nasid = optarg;
248                         break;
249                 case 'F':                                                                       /* configuration file */
250                         config_file = optarg;
251                         break;
252                 case 'e':                                                                       /* expect */
253                         expect = optarg;
254                         break;
255                 case 'r':                                                                       /* retries */
256                         if (is_intpos (optarg))
257                                 retries = atoi (optarg);
258                         else
259                                 usage (_("Number of retries must be a positive integer"));
260                         break;
261                 case 't':                                                                       /* timeout */
262                         if (is_intpos (optarg))
263                                 timeout_interval = atoi (optarg);
264                         else
265                                 usage2 (_("Timeout interval must be a positive integer"), optarg);
266                         break;
267                 }
268         }
269         return OK;
276 \f
277 void
278 print_help (void)
280         char *myport;
281         asprintf (&myport, "%d", PW_AUTH_UDP_PORT);
283         print_revision (progname, revision);
285         printf ("Copyright (c) 1999 Robert August Vincent II\n");
286         printf (COPYRIGHT, copyright, email);
288         printf(_("Tests to see if a radius server is accepting connections.\n\n"));
290         print_usage ();
292         printf (_(UT_HELP_VRSN));
294         printf (_(UT_HOST_PORT), 'P', myport);
296         printf (_("\
297  -u, --username=STRING\n\
298     The user to authenticate\n\
299  -p, --password=STRING\n\
300     Password for autentication (SECURITY RISK)\n\
301  -n, --nas-id=STRING\n\
302     NAS identifier\n\
303  -F, --filename=STRING\n\
304     Configuration file\n\
305  -e, --expect=STRING\n\
306     Response string to expect from the server\n\
307  -r, --retries=INTEGER\n\
308     Number of times to retry a failed connection\n"));
310         printf (_(UT_TIMEOUT), timeout_interval);
312         printf (_("\n\
313 This plugin tests a radius server to see if it is accepting connections.\n\
314 \n\
315 The server to test must be specified in the invocation, as well as a user\n\
316 name and password. A configuration file may also be present. The format of\n\
317 the configuration file is described in the radiusclient library sources.\n\n"));
319         printf (_("\
320 The password option presents a substantial security issue because the\n\
321 password can be determined by careful watching of the command line in\n\
322 a process listing.  This risk is exacerbated because nagios will\n\
323 run the plugin at regular prdictable intervals.  Please be sure that\n\
324 the password used does not allow access to sensitive system resources,\n\
325 otherwise compormise could occur.\n"));
327         printf (_(UT_SUPPORT));
333 void
334 print_usage (void)
336         printf ("\
337 Usage: %s -H host -F config_file -u username -p password [-n nas-id] [-P port]\n\
338   [-t timeout] [-r retries] [-e expect]\n", progname);
339         printf (_(UT_HLP_VRS), progname, progname);